TODO: ExecutePlan

This commit is contained in:
eson 2018-11-23 01:33:33 +08:00
parent 5cd76085f8
commit adc50c8a62
3 changed files with 84 additions and 20 deletions

View File

@ -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

View File

@ -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"
}

View File

@ -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())
}