diff --git a/base.go b/base.go index 2c915a7..854567c 100644 --- a/base.go +++ b/base.go @@ -7,24 +7,23 @@ import ( "reflect" ) -func buildBodyRequest(ver, url string, params *Params) *http.Request { +func buildBodyRequest(ver, rawurl string, params *Params) *http.Request { var req *http.Request var err error - if params.Body == nil { - req, err = http.NewRequest(ver, url, nil) + if params.IOBody == nil { + req, err = http.NewRequest(ver, rawurl, nil) } else { var body *bytes.Buffer - switch params.Body.(type) { + switch params.IOBody.(type) { case []byte: - body = bytes.NewBuffer(params.Body.([]byte)) + body = bytes.NewBuffer(params.IOBody.([]byte)) case *bytes.Buffer: - body = bytes.NewBuffer(params.Body.(*bytes.Buffer).Bytes()) + body = bytes.NewBuffer(params.IOBody.(*bytes.Buffer).Bytes()) default: - panic(errors.New("the type is not exist, type is" + reflect.TypeOf(params.Body).String())) + panic(errors.New("the type is not exist, type is" + reflect.TypeOf(params.IOBody).String())) } - - req, err = http.NewRequest(ver, url, body) + req, err = http.NewRequest(ver, rawurl, body) } if err != nil { diff --git a/multipart.go b/multipart.go index dbdd939..4458669 100644 --- a/multipart.go +++ b/multipart.go @@ -40,7 +40,6 @@ func createMultipart(postParams *Params, params []interface{}) { writeFormUploadFile(mwriter, p) } case string: - log.Println(param) uploadFiles, err := UploadFileFromGlob(param) if err != nil { log.Println(err) @@ -87,5 +86,5 @@ func createMultipart(postParams *Params, params []interface{}) { } postParams.ContentType = mwriter.FormDataContentType() - postParams.Body = body + postParams.IOBody = body } diff --git a/requests_method.go b/requests_method.go index ebc8dc6..032380e 100644 --- a/requests_method.go +++ b/requests_method.go @@ -2,13 +2,12 @@ package requests import ( "net/http" - "net/url" ) // Params 相关参数结构 type Params struct { // Query map[string][]string - Body interface{} + IOBody interface{} // Files []UploadFile ContentType string } @@ -40,110 +39,57 @@ func NewSession() *Session { } // Get 请求 -func (ses *Session) Get(url string) (*Response, error) { - req, err := http.NewRequest("GET", url, nil) - if err != nil { - panic(err) - } - resp, err := ses.client.Do(req) - if err != nil { - return nil, err - } - return FromHTTPResponse(resp) -} - -// SetParams 设置Post参数 -func (ses *Session) SetParams(params ...interface{}) { - plen := len(params) - defaultContentType := TypeURLENCODED - - if plen >= 2 { - t := params[plen-1] - defaultContentType = t.(string) - ses.params.ContentType = defaultContentType - } else { - ses.params.ContentType = defaultContentType - } - - if defaultContentType == TypeFormData { - // TODO: form-data - createMultipart(ses.params, 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) - } - ses.params.Body = []byte(values.Encode()) - case map[string][]string: - values = param - ses.params.Body = []byte(values.Encode()) - case string: - ses.params.Body = []byte(param) - case []byte: - ses.params.Body = param - } - } +func (ses *Session) Get(url string) *Workflow { + wf := NewWorkflow(ses) + wf.Method = "GET" + wf.SetURL(url) + return wf } // Post 请求 -func (ses *Session) Post(url string) (*Response, error) { - req := buildBodyRequest("POST", url, ses.params) - resp, err := ses.client.Do(req) - if err != nil { - return nil, err - } - return FromHTTPResponse(resp) +func (ses *Session) Post(url string) *Workflow { + wf := NewWorkflow(ses) + wf.Method = "POST" + wf.SetURL(url) + return wf } // Put 请求 -func (ses *Session) Put(url string) (*Response, error) { - req := buildBodyRequest("PUT", url, ses.params) - resp, err := ses.client.Do(req) - if err != nil { - return nil, err - } - return FromHTTPResponse(resp) +func (ses *Session) Put(url string) *Workflow { + wf := NewWorkflow(ses) + wf.Method = "PUT" + wf.SetURL(url) + return wf } // Patch 请求 -func (ses *Session) Patch(url string) (*Response, error) { - req := buildBodyRequest("PATCH", url, ses.params) - resp, err := ses.client.Do(req) - if err != nil { - return nil, err - } - return FromHTTPResponse(resp) +func (ses *Session) Patch(url string) *Workflow { + wf := NewWorkflow(ses) + wf.Method = "PATCH" + wf.SetURL(url) + return wf } // Delete 请求 -func (ses *Session) Delete(url string) (*Response, error) { - req := buildBodyRequest("DELETE", url, ses.params) - resp, err := ses.client.Do(req) - if err != nil { - return nil, err - } - return FromHTTPResponse(resp) +func (ses *Session) Delete(url string) *Workflow { + wf := NewWorkflow(ses) + wf.Method = "DELETE" + wf.SetURL(url) + return wf } // Head 请求 -func (ses *Session) Head(url string) (*Response, error) { - req := buildBodyRequest("HEAD", url, ses.params) - resp, err := ses.client.Do(req) - if err != nil { - return nil, err - } - return FromHTTPResponse(resp) +func (ses *Session) Head(url string) *Workflow { + wf := NewWorkflow(ses) + wf.Method = "HEAD" + wf.SetURL(url) + return wf } // Options 请求 -func (ses *Session) Options(url string) (*Response, error) { - req := buildBodyRequest("OPTIONS", url, ses.params) - resp, err := ses.client.Do(req) - if err != nil { - return nil, err - } - return FromHTTPResponse(resp) +func (ses *Session) Options(url string) *Workflow { + wf := NewWorkflow(ses) + wf.Method = "OPTIONS" + wf.SetURL(url) + return wf } diff --git a/requests_method_test.go b/requests_method_test.go index 655b831..99af40a 100644 --- a/requests_method_test.go +++ b/requests_method_test.go @@ -1,11 +1,16 @@ package requests import ( + "log" "net/http" "regexp" "testing" ) +func init() { + log.SetFlags(log.Lshortfile | log.LstdFlags) +} + func TestNewSession(t *testing.T) { ses := NewSession() if ses == nil { @@ -37,7 +42,7 @@ func TestSession_Get(t *testing.T) { ses := &Session{ client: tt.fields.client, } - resp, err := ses.Get(tt.args.url) + resp, err := ses.Get(tt.args.url).Execute() if err != nil { t.Error(err) } @@ -49,49 +54,40 @@ func TestSession_Get(t *testing.T) { } func TestSession_Post(t *testing.T) { - type fields struct { - client *http.Client - params *Params - } type args struct { - url string + params []interface{} } + tests := []struct { - name string - fields fields - args args - want *regexp.Regexp - wantErr bool + name string + args args + want *regexp.Regexp }{ - // TODO: Add test cases. { - name: "Post test", - fields: fields{client: &http.Client{}, params: &Params{}}, - args: args{url: "http://httpbin.org/post"}, - want: regexp.MustCompile(`"form": \{\}`), + name: "Post test", + args: args{params: nil}, + want: regexp.MustCompile(`"form": \{\}`), }, { - name: "Post data", - fields: fields{client: &http.Client{}, params: &Params{Body: []byte("a=1&b=2")}}, - args: args{url: "http://httpbin.org/post"}, - want: regexp.MustCompile(`"form": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`), + name: "Post data", + args: args{params: []interface{}{[]byte("a=1&b=2")}}, + want: regexp.MustCompile(`"form": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ses := &Session{ - client: tt.fields.client, - params: tt.fields.params, - } - got, err := ses.Post(tt.args.url) - if (err != nil) != tt.wantErr { - t.Errorf("Session.Post() error = %v, wantErr %v", err, tt.wantErr) + ses := NewSession() + got, err := ses.Post("http://httpbin.org/post").SetBodyParams(tt.args.params...).Execute() + + if err != nil { + t.Errorf("Metchod error = %v", err) return } if tt.want.MatchString(got.DContent) == false { - t.Errorf("Session.Post() = %v, want %v", got, tt.want) + t.Errorf("Metchod = %v, want %v", got, tt.want) } + }) } } @@ -113,16 +109,14 @@ func TestSession_Setparams(t *testing.T) { }{ // TODO: Add test cases. { - name: "test Setparams", - fields: fields{client: &http.Client{}, params: &Params{}}, - args: args{params: []interface{}{map[string]string{"a": "1", "b": "2"}}}, - want: regexp.MustCompile(`"form": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`), + name: "test Setparams", + args: args{params: []interface{}{map[string]string{"a": "1", "b": "2"}}}, + want: regexp.MustCompile(`"form": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`), }, { - name: "test json", - fields: fields{client: &http.Client{}, params: &Params{}}, - args: args{params: []interface{}{`{"a":"1","b":"2"}`, TypeJSON}}, - want: regexp.MustCompile(`"json": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`), + name: "test json", + args: args{params: []interface{}{`{"a":"1","b":"2"}`, TypeJSON}}, + want: regexp.MustCompile(`"json": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`), }, { name: "test xml", @@ -134,16 +128,15 @@ func TestSession_Setparams(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ses := NewSession() - ses.SetParams(tt.args.params...) - got, err := ses.Post("http://httpbin.org/post") + got, err := ses.Post("http://httpbin.org/post").SetBodyParams(tt.args.params...).Execute() if (err != nil) != tt.wantErr { - t.Errorf("Session.Post() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("Metchod error = %v, wantErr %v", err, tt.wantErr) return } if tt.want.MatchString(got.DContent) == false { - t.Errorf("Session.Post() = %v, want %v", got, tt.want) + t.Errorf("Metchod = %v, want %v", got, tt.want) } }) } @@ -178,16 +171,15 @@ func TestSession_PostUploadFile(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ses := NewSession() - ses.SetParams(tt.args.params, TypeFormData) - got, err := ses.Post("http://httpbin.org/post") + got, err := ses.Post("http://httpbin.org/post").SetBodyParams(tt.args.params, TypeFormData).Execute() if err != nil { - t.Errorf("Session.Post() error = %v", err) + t.Errorf("Metchod error = %v", err) return } if tt.want.MatchString(got.DContent) == false { - t.Errorf("Session.Post() = %v, want %v", got, tt.want) + t.Errorf("Metchod = %v, want %v", got, tt.want) } }) @@ -223,16 +215,15 @@ func TestSession_Put(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ses := NewSession() - ses.SetParams(tt.args.params, TypeFormData) - got, err := ses.Put("http://httpbin.org/put") + got, err := ses.Put("http://httpbin.org/put").SetBodyParams(tt.args.params, TypeFormData).Execute() if err != nil { - t.Errorf("Session.Post() error = %v", err) + t.Errorf("Metchod error = %v", err) return } if tt.want.MatchString(got.DContent) == false { - t.Errorf("Session.Post() = %v, want %v", got, tt.want) + t.Errorf("Metchod = %v, want %v", got, tt.want) } }) @@ -268,16 +259,15 @@ func TestSession_Patch(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ses := NewSession() - ses.SetParams(tt.args.params, TypeFormData) - got, err := ses.Patch("http://httpbin.org/patch") + got, err := ses.Patch("http://httpbin.org/patch").SetBodyParams(tt.args.params, TypeFormData).Execute() if err != nil { - t.Errorf("Session.Post() error = %v", err) + t.Errorf("Metchod error = %v", err) return } if tt.want.MatchString(got.DContent) == false { - t.Errorf("Session.Post() = %v, want %v", got, tt.want) + t.Errorf("Metchod = %v, want %v", got, tt.want) } }) diff --git a/response_test.go b/response_test.go index 523a338..871910a 100644 --- a/response_test.go +++ b/response_test.go @@ -1 +1,9 @@ package requests + +import ( + "testing" +) + +func TestURL(t *testing.T) { + +} diff --git a/workflow.go b/workflow.go index 1e3d2d1..43c959b 100644 --- a/workflow.go +++ b/workflow.go @@ -1,20 +1,23 @@ package requests -import "net/url" +import ( + "net/url" + "regexp" +) // Workflow 工作流 type Workflow struct { - session *Session - URL string - Method string - Body *Params - Query map[string][]string + session *Session + ParsedURL *url.URL + Method string + Body *Params } // NewWorkflow new and init workflow func NewWorkflow(ses *Session) *Workflow { wf := &Workflow{} wf.SwitchSession(ses) + wf.Body = &Params{} return wf } @@ -23,8 +26,84 @@ func (wf *Workflow) SwitchSession(ses *Session) { wf.session = ses } -// SetParams 参数设置 -func (wf *Workflow) SetParams(params ...interface{}) *Workflow { +// 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 设置Path参数 +func (wf *Workflow) SetURLRawPath(path string) *Workflow { + wf.ParsedURL.Path = path + return wf +} + +// SetBodyParams 参数设置 +func (wf *Workflow) SetBodyParams(params ...interface{}) *Workflow { + if params == nil { + return wf + } + plen := len(params) defaultContentType := TypeURLENCODED @@ -47,14 +126,14 @@ func (wf *Workflow) SetParams(params ...interface{}) *Workflow { for k, v := range param { values.Set(k, v) } - wf.Body.Body = []byte(values.Encode()) + wf.Body.IOBody = []byte(values.Encode()) case map[string][]string: values = param - wf.Body.Body = []byte(values.Encode()) + wf.Body.IOBody = []byte(values.Encode()) case string: - wf.Body.Body = []byte(param) + wf.Body.IOBody = []byte(param) case []byte: - wf.Body.Body = param + wf.Body.IOBody = param } } return wf @@ -62,7 +141,7 @@ func (wf *Workflow) SetParams(params ...interface{}) *Workflow { // Execute 执行 func (wf *Workflow) Execute() (*Response, error) { - req := buildBodyRequest(wf.Method, wf.URL, wf.Body) + req := buildBodyRequest(wf.Method, wf.GetStringURL(), wf.Body) resp, err := wf.session.client.Do(req) if err != nil { return nil, err