diff --git a/base.go b/base.go index 4591616..9507356 100644 --- a/base.go +++ b/base.go @@ -15,6 +15,11 @@ type ParseFunction struct { Prioty int } +// Execute 执行 函数 +func (pf *ParseFunction) Execute() { + pf.ExecuteFunction(pf.ParamCURL, pf.ParamData) +} + // Swap 实现sort.Iterface func (nodes *Nodes) Swap(i, j int) { ns := *nodes @@ -61,7 +66,6 @@ func NewPQueueExecute() *PQueueExecute { // Push Create A PQueueExecute func (pqe *PQueueExecute) Push(exec *ParseFunction) { heap.Push(&pqe.nodes, exec) - heap.Fix(&pqe.nodes, pqe.Len()-1) } // Pop Create A PQueueExecute diff --git a/parse_curl.go b/parse_curl.go index 78c5e88..ee101b5 100644 --- a/parse_curl.go +++ b/parse_curl.go @@ -12,7 +12,7 @@ import ( "regexp" "strings" - "github.com/474420502/requests" + "474420502.top/eson/requests" ) // CURL 信息结构 @@ -23,6 +23,8 @@ type CURL struct { CookieJar http.CookieJar Cookies []*http.Cookie Body *requests.Body + Auth *requests.BasicAuth + Insecure bool } // NewCURL new 一个 curl 出来 @@ -42,6 +44,8 @@ func NewCURL(scurl ...string) *CURL { } u := &CURL{} + u.Insecure = false + u.Header = make(http.Header) u.CookieJar, _ = cookiejar.New(nil) u.Body = requests.NewBody() @@ -59,12 +63,22 @@ func (curl *CURL) CreateSession() *requests.Session { ses := requests.NewSession() ses.SetHeader(curl.Header) ses.SetCookies(curl.ParsedURL, curl.Cookies) + + if curl.Auth != nil { + ses.SetConfig(requests.CBasicAuth, curl.Auth) + } + + if curl.Insecure { + ses.SetConfig(requests.CInsecure, curl.Insecure) + } + return ses } // CreateWorkflow 根据Session 创建Workflow func (curl *CURL) CreateWorkflow(ses *requests.Session) *requests.Workflow { var wf *requests.Workflow + switch curl.Method { case "HEAD": wf = ses.Head(curl.ParsedURL.String()) @@ -96,6 +110,8 @@ func ParseRawCURL(scurl string) (cURL *CURL, err error) { } }() + executor := NewPQueueExecute() + curl := NewCURL() scurl = strings.TrimSpace(scurl) scurl = strings.TrimLeft(scurl, "curl") @@ -110,10 +126,18 @@ func ParseRawCURL(scurl string) (cURL *CURL, err error) { } curl.ParsedURL = purl case '-': - judgeAndParseOptions(curl, m) + exec := judgeAndParseOptions(curl, m) + if exec != nil { + executor.Push(exec) + } } } + for executor.Len() > 0 { + exec := executor.Pop() + exec.Execute() + } + if curl.Method == "" { curl.Method = "GET" } @@ -124,15 +148,24 @@ func ParseRawCURL(scurl string) (cURL *CURL, err error) { func judgeAndParseOptions(u *CURL, soption string) *ParseFunction { switch prefix := soption[0:2]; prefix { case "-H": - return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseHeader, Prioty: 1} + return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseHeader, Prioty: 10} case "-X": - return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseOptX, Prioty: 1} + return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseOptX, Prioty: 10} case "-A": // User-Agent 先后顺序的问题 - return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseHeader, Prioty: 1} + data := extractData("^-A +(.+)", soption) + return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseUserAgent, Prioty: 15} case "-I": - return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseOptI, Prioty: 1} + return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseOptI, Prioty: 15} case "--": return parseLongOption(u, soption) + case "-d": + data := extractData("^-d +(.+)", soption) + return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyASCII, Prioty: 10} + case "-u": + data := extractData("^-u +(.+)", soption) + return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseUser, Prioty: 15} + case "-k": // -k, --insecure Allow insecure server connections when using SSL + return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseInsecure, Prioty: 15} } return nil } @@ -146,8 +179,8 @@ func parseLongOption(u *CURL, soption string) *ParseFunction { switch { case regexp.MustCompile("^--data |^--data-urlencode|^--data-binary|^--data-ascii|^--data-raw").MatchString(soption): - datas := regexp.MustCompile("^--data-(binary) +(.+)|^--data-(ascii) +(.+)|^--data-(raw) +(.+)|^--data-(urlencode) +(.+)|^--(data) +(.+)").FindStringSubmatch(soption) + datas := regexp.MustCompile("^--data-(binary) +(.+)|^--data-(ascii) +(.+)|^--data-(raw) +(.+)|^--data-(urlencode) +(.+)|^--(data) +(.+)").FindStringSubmatch(soption) dtype := datas[1] data := strings.Trim(datas[2], "'") @@ -157,24 +190,51 @@ func parseLongOption(u *CURL, soption string) *ParseFunction { switch dtype { case "binary": - return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyBinary, Prioty: 1} + return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyBinary, Prioty: 10} case "ascii": - return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyASCII, Prioty: 1} + return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyASCII, Prioty: 10} case "raw": - return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyRaw, Prioty: 1} + return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyRaw, Prioty: 10} case "urlencode": - return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyURLEncode, Prioty: 1} + return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyURLEncode, Prioty: 10} case "data": - return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyASCII, Prioty: 1} + return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseBodyASCII, Prioty: 10} } + case regexp.MustCompile("^--header").MatchString(soption): - return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseHeader, Prioty: 1} + return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseHeader, Prioty: 10} + case regexp.MustCompile("^--user-agent").MatchString(soption): + data := extractData("^--user-agent +(.+)", soption) + return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseUserAgent, Prioty: 15} + case regexp.MustCompile("^--user").MatchString(soption): + data := extractData("^--user +(.+)", soption) + return &ParseFunction{ParamCURL: u, ParamData: data, ExecuteFunction: parseUser, Prioty: 15} + case regexp.MustCompile("^--insecure").MatchString(soption): + return &ParseFunction{ParamCURL: u, ParamData: soption, ExecuteFunction: parseInsecure, Prioty: 15} } log.Println("can't parseOption", soption) return nil } +func extractData(re, soption string) string { + datas := regexp.MustCompile(re).FindStringSubmatch(soption) + return strings.Trim(datas[1], "'") +} + +func parseInsecure(u *CURL, soption string) { + u.Insecure = true +} + +func parseUser(u *CURL, soption string) { + auth := strings.Split(soption, ":") + u.Auth = &requests.BasicAuth{User: auth[0], Password: auth[1]} +} + +func parseUserAgent(u *CURL, value string) { + u.Header.Add("User-Agent", value) +} + func parseOptI(u *CURL, soption string) { u.Method = "HEAD" } diff --git a/parse_curl_test.go b/parse_curl_test.go index 0a470f9..e4b5779 100644 --- a/parse_curl_test.go +++ b/parse_curl_test.go @@ -24,12 +24,12 @@ func TestParseCURL(t *testing.T) { for _, scurl := range scurls { curl, err := ParseRawCURL(scurl) if err != nil { - t.Error(err, "\n", curl.String()) + t.Error(err) + } else { + if curl.Method == "" { + t.Error("curl.Method is nil") + } } - if curl.Method == "" { - t.Error("curl.Method is nil") - } - } } @@ -46,5 +46,5 @@ func TestTouTiaoCURL(t *testing.T) { if err != nil { t.Error(err) } - t.Log(curl, resp.Content()) + t.Log(curl, "Content:\n", resp.Content()) }