新版v0.0.1

This commit is contained in:
huangsimin 2018-10-17 18:38:04 +08:00
parent dc1baf12c1
commit 79f1bf54df
6 changed files with 187 additions and 166 deletions

17
base.go
View File

@ -7,24 +7,23 @@ import (
"reflect" "reflect"
) )
func buildBodyRequest(ver, url string, params *Params) *http.Request { func buildBodyRequest(ver, rawurl string, params *Params) *http.Request {
var req *http.Request var req *http.Request
var err error var err error
if params.Body == nil { if params.IOBody == nil {
req, err = http.NewRequest(ver, url, nil) req, err = http.NewRequest(ver, rawurl, nil)
} else { } else {
var body *bytes.Buffer var body *bytes.Buffer
switch params.Body.(type) { switch params.IOBody.(type) {
case []byte: case []byte:
body = bytes.NewBuffer(params.Body.([]byte)) body = bytes.NewBuffer(params.IOBody.([]byte))
case *bytes.Buffer: case *bytes.Buffer:
body = bytes.NewBuffer(params.Body.(*bytes.Buffer).Bytes()) body = bytes.NewBuffer(params.IOBody.(*bytes.Buffer).Bytes())
default: 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, rawurl, body)
req, err = http.NewRequest(ver, url, body)
} }
if err != nil { if err != nil {

View File

@ -40,7 +40,6 @@ func createMultipart(postParams *Params, params []interface{}) {
writeFormUploadFile(mwriter, p) writeFormUploadFile(mwriter, p)
} }
case string: case string:
log.Println(param)
uploadFiles, err := UploadFileFromGlob(param) uploadFiles, err := UploadFileFromGlob(param)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
@ -87,5 +86,5 @@ func createMultipart(postParams *Params, params []interface{}) {
} }
postParams.ContentType = mwriter.FormDataContentType() postParams.ContentType = mwriter.FormDataContentType()
postParams.Body = body postParams.IOBody = body
} }

View File

@ -2,13 +2,12 @@ package requests
import ( import (
"net/http" "net/http"
"net/url"
) )
// Params 相关参数结构 // Params 相关参数结构
type Params struct { type Params struct {
// Query map[string][]string // Query map[string][]string
Body interface{} IOBody interface{}
// Files []UploadFile // Files []UploadFile
ContentType string ContentType string
} }
@ -40,110 +39,57 @@ func NewSession() *Session {
} }
// Get 请求 // Get 请求
func (ses *Session) Get(url string) (*Response, error) { func (ses *Session) Get(url string) *Workflow {
req, err := http.NewRequest("GET", url, nil) wf := NewWorkflow(ses)
if err != nil { wf.Method = "GET"
panic(err) wf.SetURL(url)
} return wf
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
}
}
} }
// Post 请求 // Post 请求
func (ses *Session) Post(url string) (*Response, error) { func (ses *Session) Post(url string) *Workflow {
req := buildBodyRequest("POST", url, ses.params) wf := NewWorkflow(ses)
resp, err := ses.client.Do(req) wf.Method = "POST"
if err != nil { wf.SetURL(url)
return nil, err return wf
}
return FromHTTPResponse(resp)
} }
// Put 请求 // Put 请求
func (ses *Session) Put(url string) (*Response, error) { func (ses *Session) Put(url string) *Workflow {
req := buildBodyRequest("PUT", url, ses.params) wf := NewWorkflow(ses)
resp, err := ses.client.Do(req) wf.Method = "PUT"
if err != nil { wf.SetURL(url)
return nil, err return wf
}
return FromHTTPResponse(resp)
} }
// Patch 请求 // Patch 请求
func (ses *Session) Patch(url string) (*Response, error) { func (ses *Session) Patch(url string) *Workflow {
req := buildBodyRequest("PATCH", url, ses.params) wf := NewWorkflow(ses)
resp, err := ses.client.Do(req) wf.Method = "PATCH"
if err != nil { wf.SetURL(url)
return nil, err return wf
}
return FromHTTPResponse(resp)
} }
// Delete 请求 // Delete 请求
func (ses *Session) Delete(url string) (*Response, error) { func (ses *Session) Delete(url string) *Workflow {
req := buildBodyRequest("DELETE", url, ses.params) wf := NewWorkflow(ses)
resp, err := ses.client.Do(req) wf.Method = "DELETE"
if err != nil { wf.SetURL(url)
return nil, err return wf
}
return FromHTTPResponse(resp)
} }
// Head 请求 // Head 请求
func (ses *Session) Head(url string) (*Response, error) { func (ses *Session) Head(url string) *Workflow {
req := buildBodyRequest("HEAD", url, ses.params) wf := NewWorkflow(ses)
resp, err := ses.client.Do(req) wf.Method = "HEAD"
if err != nil { wf.SetURL(url)
return nil, err return wf
}
return FromHTTPResponse(resp)
} }
// Options 请求 // Options 请求
func (ses *Session) Options(url string) (*Response, error) { func (ses *Session) Options(url string) *Workflow {
req := buildBodyRequest("OPTIONS", url, ses.params) wf := NewWorkflow(ses)
resp, err := ses.client.Do(req) wf.Method = "OPTIONS"
if err != nil { wf.SetURL(url)
return nil, err return wf
}
return FromHTTPResponse(resp)
} }

View File

@ -1,11 +1,16 @@
package requests package requests
import ( import (
"log"
"net/http" "net/http"
"regexp" "regexp"
"testing" "testing"
) )
func init() {
log.SetFlags(log.Lshortfile | log.LstdFlags)
}
func TestNewSession(t *testing.T) { func TestNewSession(t *testing.T) {
ses := NewSession() ses := NewSession()
if ses == nil { if ses == nil {
@ -37,7 +42,7 @@ func TestSession_Get(t *testing.T) {
ses := &Session{ ses := &Session{
client: tt.fields.client, client: tt.fields.client,
} }
resp, err := ses.Get(tt.args.url) resp, err := ses.Get(tt.args.url).Execute()
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -49,49 +54,40 @@ func TestSession_Get(t *testing.T) {
} }
func TestSession_Post(t *testing.T) { func TestSession_Post(t *testing.T) {
type fields struct {
client *http.Client
params *Params
}
type args struct { type args struct {
url string params []interface{}
} }
tests := []struct { tests := []struct {
name string name string
fields fields args args
args args want *regexp.Regexp
want *regexp.Regexp
wantErr bool
}{ }{
// TODO: Add test cases.
{ {
name: "Post test", name: "Post test",
fields: fields{client: &http.Client{}, params: &Params{}}, args: args{params: nil},
args: args{url: "http://httpbin.org/post"}, want: regexp.MustCompile(`"form": \{\}`),
want: regexp.MustCompile(`"form": \{\}`),
}, },
{ {
name: "Post data", name: "Post data",
fields: fields{client: &http.Client{}, params: &Params{Body: []byte("a=1&b=2")}}, args: args{params: []interface{}{[]byte("a=1&b=2")}},
args: args{url: "http://httpbin.org/post"}, want: regexp.MustCompile(`"form": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`),
want: regexp.MustCompile(`"form": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`),
}, },
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ses := &Session{ ses := NewSession()
client: tt.fields.client, got, err := ses.Post("http://httpbin.org/post").SetBodyParams(tt.args.params...).Execute()
params: tt.fields.params,
} if err != nil {
got, err := ses.Post(tt.args.url) t.Errorf("Metchod error = %v", err)
if (err != nil) != tt.wantErr {
t.Errorf("Session.Post() error = %v, wantErr %v", err, tt.wantErr)
return return
} }
if tt.want.MatchString(got.DContent) == false { 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. // TODO: Add test cases.
{ {
name: "test Setparams", name: "test Setparams",
fields: fields{client: &http.Client{}, params: &Params{}}, args: args{params: []interface{}{map[string]string{"a": "1", "b": "2"}}},
args: args{params: []interface{}{map[string]string{"a": "1", "b": "2"}}}, want: regexp.MustCompile(`"form": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`),
want: regexp.MustCompile(`"form": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`),
}, },
{ {
name: "test json", name: "test json",
fields: fields{client: &http.Client{}, params: &Params{}}, args: args{params: []interface{}{`{"a":"1","b":"2"}`, TypeJSON}},
args: args{params: []interface{}{`{"a":"1","b":"2"}`, TypeJSON}}, want: regexp.MustCompile(`"json": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`),
want: regexp.MustCompile(`"json": \{[^"]+"a": "1"[^"]+"b": "2"[^\}]+\}`),
}, },
{ {
name: "test xml", name: "test xml",
@ -134,16 +128,15 @@ func TestSession_Setparams(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ses := NewSession() 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 { 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 return
} }
if tt.want.MatchString(got.DContent) == false { 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 { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ses := NewSession() ses := NewSession()
ses.SetParams(tt.args.params, TypeFormData) got, err := ses.Post("http://httpbin.org/post").SetBodyParams(tt.args.params, TypeFormData).Execute()
got, err := ses.Post("http://httpbin.org/post")
if err != nil { if err != nil {
t.Errorf("Session.Post() error = %v", err) t.Errorf("Metchod error = %v", err)
return return
} }
if tt.want.MatchString(got.DContent) == false { 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 { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ses := NewSession() ses := NewSession()
ses.SetParams(tt.args.params, TypeFormData) got, err := ses.Put("http://httpbin.org/put").SetBodyParams(tt.args.params, TypeFormData).Execute()
got, err := ses.Put("http://httpbin.org/put")
if err != nil { if err != nil {
t.Errorf("Session.Post() error = %v", err) t.Errorf("Metchod error = %v", err)
return return
} }
if tt.want.MatchString(got.DContent) == false { 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 { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ses := NewSession() ses := NewSession()
ses.SetParams(tt.args.params, TypeFormData) got, err := ses.Patch("http://httpbin.org/patch").SetBodyParams(tt.args.params, TypeFormData).Execute()
got, err := ses.Patch("http://httpbin.org/patch")
if err != nil { if err != nil {
t.Errorf("Session.Post() error = %v", err) t.Errorf("Metchod error = %v", err)
return return
} }
if tt.want.MatchString(got.DContent) == false { 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)
} }
}) })

View File

@ -1 +1,9 @@
package requests package requests
import (
"testing"
)
func TestURL(t *testing.T) {
}

View File

@ -1,20 +1,23 @@
package requests package requests
import "net/url" import (
"net/url"
"regexp"
)
// Workflow 工作流 // Workflow 工作流
type Workflow struct { type Workflow struct {
session *Session session *Session
URL string ParsedURL *url.URL
Method string Method string
Body *Params Body *Params
Query map[string][]string
} }
// NewWorkflow new and init workflow // NewWorkflow new and init workflow
func NewWorkflow(ses *Session) *Workflow { func NewWorkflow(ses *Session) *Workflow {
wf := &Workflow{} wf := &Workflow{}
wf.SwitchSession(ses) wf.SwitchSession(ses)
wf.Body = &Params{}
return wf return wf
} }
@ -23,8 +26,84 @@ func (wf *Workflow) SwitchSession(ses *Session) {
wf.session = ses wf.session = ses
} }
// SetParams 参数设置 // GetStringURL 获取url的string形式
func (wf *Workflow) SetParams(params ...interface{}) *Workflow { 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) plen := len(params)
defaultContentType := TypeURLENCODED defaultContentType := TypeURLENCODED
@ -47,14 +126,14 @@ func (wf *Workflow) SetParams(params ...interface{}) *Workflow {
for k, v := range param { for k, v := range param {
values.Set(k, v) values.Set(k, v)
} }
wf.Body.Body = []byte(values.Encode()) wf.Body.IOBody = []byte(values.Encode())
case map[string][]string: case map[string][]string:
values = param values = param
wf.Body.Body = []byte(values.Encode()) wf.Body.IOBody = []byte(values.Encode())
case string: case string:
wf.Body.Body = []byte(param) wf.Body.IOBody = []byte(param)
case []byte: case []byte:
wf.Body.Body = param wf.Body.IOBody = param
} }
} }
return wf return wf
@ -62,7 +141,7 @@ func (wf *Workflow) SetParams(params ...interface{}) *Workflow {
// Execute 执行 // Execute 执行
func (wf *Workflow) Execute() (*Response, error) { 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) resp, err := wf.session.client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err