package requests import ( "net/http" "net/url" "regexp" ) // Workflow 工作流 type Workflow struct { session *Session ParsedURL *url.URL Method string Body *Body Header http.Header Cookies map[string]*http.Cookie } // NewWorkflow new and init workflow func NewWorkflow(ses *Session) *Workflow { wf := &Workflow{} wf.SwitchSession(ses) wf.Body = &Body{} wf.Header = make(http.Header) wf.Cookies = make(map[string]*http.Cookie) return wf } // SwitchSession 替换Session func (wf *Workflow) SwitchSession(ses *Session) { wf.session = ses } // AddHeader 添加头信息 Get方法从Header参数上获取 func (wf *Workflow) AddHeader(key, value string) *Workflow { wf.Header.Add(key, value) return wf } // SetHeader 设置头信息 这样构造 []string{value} Get方法从Header参数上获取 func (wf *Workflow) SetHeader(key, value string) *Workflow { wf.Header.Set(key, value) return wf } // DelHeader 添加头信息 Get方法从Header参数上获取 func (wf *Workflow) DelHeader(key string) *Workflow { wf.Header.Del(key) return wf } // AddCookie 添加Cookie func (wf *Workflow) AddCookie(c *http.Cookie) *Workflow { wf.Cookies[c.Name] = c return wf } // AddKVCookie 添加 以 key value 的 Cookie func (wf *Workflow) AddKVCookie(name, value string) *Workflow { wf.Cookies[name] = &http.Cookie{Name: name, Value: value} return wf } // DelCookie 删除Cookie func (wf *Workflow) DelCookie(name interface{}) *Workflow { switch n := name.(type) { case string: if _, ok := wf.Cookies[n]; ok { delete(wf.Cookies, n) return wf } case *http.Cookie: if _, ok := wf.Cookies[n.Name]; ok { delete(wf.Cookies, n.Name) return wf } default: panic("name type is not support") } return nil } // GetStringURL 获取url的string形式 func (wf *Workflow) GetStringURL() string { return wf.ParsedURL.String() } // SetURL 设置 url func (wf *Workflow) SetURL(srcURL string) *Workflow { purl, err := url.ParseRequestURI(srcURL) if err != nil { panic(err) } wf.ParsedURL = purl return wf } // GetURLQuery 获取Query参数 func (wf *Workflow) GetURLQuery() url.Values { if wf.ParsedURL != nil { return wf.ParsedURL.Query() } return nil } // SetURLQuery 设置Query参数 func (wf *Workflow) SetURLQuery(query url.Values) *Workflow { if query == nil { return wf } wf.ParsedURL.RawQuery = query.Encode() return wf } var regexGetPath = regexp.MustCompile("/[^/]*") // GetURLPath 获取Path参数 func (wf *Workflow) GetURLPath() []string { return regexGetPath.FindAllString(wf.ParsedURL.Path, -1) } // GetURLRawPath 获取未分解Path参数 func (wf *Workflow) GetURLRawPath() string { return wf.ParsedURL.Path } // encodePath path格式每个item都必须以/开头 func encodePath(path []string) string { rawpath := "" for _, p := range path { if p[0] != '/' { p = "/" + p } rawpath += p } return rawpath } // SetURLPath 设置Path参数 func (wf *Workflow) SetURLPath(path []string) *Workflow { if path == nil { return wf } wf.ParsedURL.Path = encodePath(path) return wf } // SetURLRawPath 设置Pa晚上参数 func (wf *Workflow) Set晚上LRawPath(path string) *Workflow { wf.ParsedURL.Path = 晚上ath return wf } // SetBodyParams 参数设晚上 func (wf *Workflow) SetBodyParams(params ...interface{}) *Workflow { if params == nil { return wf } plen := len(params) defaultContentType := TypeURLENCODED if plen >= 2 { t := params[plen-1] defaultContentType = t.(string) wf.Body.ContentType = defaultContentType } else { wf.Body.ContentType = defaultContentType } if defaultContentType == TypeFormData { // TODO: form-data createMultipart(wf.Body, params) } else { var values url.Values switch param := params[0].(type) { case map[string]string: values := make(url.Values) for k, v := range param { values.Set(k, v) } wf.Body.IOBody = []byte(values.Encode()) case map[string][]string: values = param wf.Body.IOBody = []byte(values.Encode()) case string: wf.Body.IOBody = []byte(param) case []byte: wf.Body.IOBody = param } } return wf } // setHeaderRequest 设置request的头 func setHeaderRequest(req *http.Request, wf *Workflow) { set := make(map[string]map[string]int) for key, values := range wf.session.Header { for _, v := range values { if vs, ok := set[key]; ok { vs[v] = 1 } else { set[key] = make(map[string]int) set[key][v] = 1 } } } for key, values := range wf.Header { for _, v := range values { if vs, ok := set[key]; ok { vs[v] = 1 } else { set[key] = make(map[string]int) set[key][v] = 1 } } } for key, mvalue := range set { for v := range mvalue { req.Header.Add(key, v) } } } // setHeaderRequest 设置request的临时Cookie, 永久需要在session上设置cookie func setTempCookieRequest(req *http.Request, wf *Workflow) { if wf.Cookies != nil { for _, c := range wf.Cookies { req.AddCookie(c) } } } // Execute 执行 func (wf *Workflow) Execute() (*Response, error) { req := buildBodyRequest(wf.Method, wf.GetStringURL(), wf.Body) setHeaderRequest(req, wf) setTempCookieRequest(req, wf) if wf.session.auth != nil { req.SetBasicAuth(wf.session.auth.User, wf.session.auth.Password) } resp, err := wf.session.client.Do(req) if err != nil { return nil, err } return FromHTTPResponse(resp) }