改版前
This commit is contained in:
commit
dc1baf12c1
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*.pyc
|
42
base.go
Normal file
42
base.go
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package requests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func buildBodyRequest(ver, url string, params *Params) *http.Request {
|
||||||
|
var req *http.Request
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if params.Body == nil {
|
||||||
|
req, err = http.NewRequest(ver, url, nil)
|
||||||
|
} else {
|
||||||
|
var body *bytes.Buffer
|
||||||
|
switch params.Body.(type) {
|
||||||
|
case []byte:
|
||||||
|
body = bytes.NewBuffer(params.Body.([]byte))
|
||||||
|
case *bytes.Buffer:
|
||||||
|
body = bytes.NewBuffer(params.Body.(*bytes.Buffer).Bytes())
|
||||||
|
default:
|
||||||
|
panic(errors.New("the type is not exist, type is" + reflect.TypeOf(params.Body).String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err = http.NewRequest(ver, url, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.ContentType == "" {
|
||||||
|
req.Header.Set("Content-Type", TypeURLENCODED)
|
||||||
|
} else {
|
||||||
|
req.Header.Set("Content-Type", params.ContentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return req
|
||||||
|
|
||||||
|
}
|
5
httpclient_method.go
Normal file
5
httpclient_method.go
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package requests
|
||||||
|
|
||||||
|
func Get(url string) {
|
||||||
|
|
||||||
|
}
|
9
httpclient_method_test.go
Normal file
9
httpclient_method_test.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package requests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGet(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
91
multipart.go
Normal file
91
multipart.go
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
package requests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"mime/multipart"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func writeFormUploadFile(mwriter *multipart.Writer, ufile *UploadFile) {
|
||||||
|
part, err := mwriter.CreateFormFile(ufile.FieldName, ufile.FileName)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
io.Copy(part, ufile.FileReaderCloser)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createMultipart(postParams *Params, params []interface{}) {
|
||||||
|
plen := len(params)
|
||||||
|
|
||||||
|
body := &bytes.Buffer{}
|
||||||
|
mwriter := multipart.NewWriter(body)
|
||||||
|
|
||||||
|
defer mwriter.Close()
|
||||||
|
|
||||||
|
for _, iparam := range params[0 : plen-1] {
|
||||||
|
switch param := iparam.(type) {
|
||||||
|
case *UploadFile:
|
||||||
|
if param.FieldName == "" {
|
||||||
|
param.FieldName = "file0"
|
||||||
|
}
|
||||||
|
writeFormUploadFile(mwriter, param)
|
||||||
|
case []*UploadFile:
|
||||||
|
for i, p := range param {
|
||||||
|
if p.FieldName == "" {
|
||||||
|
p.FieldName = "file" + strconv.Itoa(i)
|
||||||
|
}
|
||||||
|
writeFormUploadFile(mwriter, p)
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
log.Println(param)
|
||||||
|
uploadFiles, err := UploadFileFromGlob(param)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
} else {
|
||||||
|
for i, p := range uploadFiles {
|
||||||
|
if p.FieldName == "" {
|
||||||
|
p.FieldName = "file" + strconv.Itoa(i)
|
||||||
|
}
|
||||||
|
writeFormUploadFile(mwriter, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case []string:
|
||||||
|
for i, glob := range param {
|
||||||
|
uploadFiles, err := UploadFileFromGlob(glob)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
} else {
|
||||||
|
for ii, p := range uploadFiles {
|
||||||
|
if p.FieldName == "" {
|
||||||
|
p.FieldName = "file" + strconv.Itoa(ii) + "_" + strconv.Itoa(i)
|
||||||
|
}
|
||||||
|
writeFormUploadFile(mwriter, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case map[string]string:
|
||||||
|
for k, v := range param {
|
||||||
|
mwriter.WriteField(k, v)
|
||||||
|
}
|
||||||
|
case map[string][]string:
|
||||||
|
for k, vs := range param {
|
||||||
|
for _, v := range vs {
|
||||||
|
mwriter.WriteField(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case url.Values:
|
||||||
|
for k, vs := range param {
|
||||||
|
for _, v := range vs {
|
||||||
|
mwriter.WriteField(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
postParams.ContentType = mwriter.FormDataContentType()
|
||||||
|
postParams.Body = body
|
||||||
|
}
|
149
requests_method.go
Normal file
149
requests_method.go
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
package requests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Params 相关参数结构
|
||||||
|
type Params struct {
|
||||||
|
// Query map[string][]string
|
||||||
|
Body interface{}
|
||||||
|
// Files []UploadFile
|
||||||
|
ContentType string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Session 的基本方法
|
||||||
|
type Session struct {
|
||||||
|
client *http.Client
|
||||||
|
params *Params
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeContent post类型参数
|
||||||
|
type TypeContent int
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ TypeContent = iota
|
||||||
|
// TypeJSON 类型
|
||||||
|
TypeJSON = "application/json"
|
||||||
|
// TypeXML 类型
|
||||||
|
TypeXML = "text/xml"
|
||||||
|
// TypeURLENCODED 类型
|
||||||
|
TypeURLENCODED = "application/x-www-form-urlencoded"
|
||||||
|
// TypeFormData 类型
|
||||||
|
TypeFormData = "multipart/form-data"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewSession 创建Session
|
||||||
|
func NewSession() *Session {
|
||||||
|
return &Session{client: &http.Client{}, params: &Params{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
285
requests_method_test.go
Normal file
285
requests_method_test.go
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
package requests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewSession(t *testing.T) {
|
||||||
|
ses := NewSession()
|
||||||
|
if ses == nil {
|
||||||
|
t.Error("session create fail, value is nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSession_Get(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
client *http.Client
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
url string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
{
|
||||||
|
name: "Get test",
|
||||||
|
fields: fields{client: &http.Client{}},
|
||||||
|
args: args{url: "http://httpbin.org/get"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
ses := &Session{
|
||||||
|
client: tt.fields.client,
|
||||||
|
}
|
||||||
|
resp, err := ses.Get(tt.args.url)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if len(resp.Content()) <= 200 {
|
||||||
|
t.Error(resp.Content())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSession_Post(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
client *http.Client
|
||||||
|
params *Params
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
url string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
want *regexp.Regexp
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// 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 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"[^\}]+\}`),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.want.MatchString(got.DContent) == false {
|
||||||
|
t.Errorf("Session.Post() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSession_Setparams(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
client *http.Client
|
||||||
|
params *Params
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
params []interface{}
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
want *regexp.Regexp
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// 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 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 xml",
|
||||||
|
fields: fields{client: &http.Client{}, params: &Params{}},
|
||||||
|
args: args{params: []interface{}{`<request><parameters><password>test</password></parameters></request>`, TypeXML}},
|
||||||
|
want: regexp.MustCompile(`"data": "<request><parameters><password>test</password></parameters></request>"`),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Session.Post() 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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSession_PostUploadFile(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
params interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want *regexp.Regexp
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test post uploadfile glob",
|
||||||
|
args: args{params: "tests/*.js"},
|
||||||
|
want: regexp.MustCompile(`"file0": "data:application/octet-stream;base64`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test post uploadfile only one file",
|
||||||
|
args: args{params: "tests/json.file"},
|
||||||
|
want: regexp.MustCompile(`"file0": "json.file.+jsonjsonjsonjson"`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test post uploadfile key values",
|
||||||
|
args: args{params: map[string]string{"a": "32"}},
|
||||||
|
want: regexp.MustCompile(`"a": "32"`),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Session.Post() error = %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.want.MatchString(got.DContent) == false {
|
||||||
|
t.Errorf("Session.Post() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSession_Put(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
params interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want *regexp.Regexp
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test post uploadfile glob",
|
||||||
|
args: args{params: "tests/*.js"},
|
||||||
|
want: regexp.MustCompile(`"file0": "data:application/octet-stream;base64`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test post uploadfile only one file",
|
||||||
|
args: args{params: "tests/json.file"},
|
||||||
|
want: regexp.MustCompile(`"file0": "json.file.+jsonjsonjsonjson"`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test post uploadfile key values",
|
||||||
|
args: args{params: map[string]string{"a": "32"}},
|
||||||
|
want: regexp.MustCompile(`"a": "32"`),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Session.Post() error = %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.want.MatchString(got.DContent) == false {
|
||||||
|
t.Errorf("Session.Post() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSession_Patch(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
params interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want *regexp.Regexp
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test post uploadfile glob",
|
||||||
|
args: args{params: "tests/*.js"},
|
||||||
|
want: regexp.MustCompile(`"file0": "data:application/octet-stream;base64`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test post uploadfile only one file",
|
||||||
|
args: args{params: "tests/json.file"},
|
||||||
|
want: regexp.MustCompile(`"file0": "json.file.+jsonjsonjsonjson"`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test post uploadfile key values",
|
||||||
|
args: args{params: map[string]string{"a": "32"}},
|
||||||
|
want: regexp.MustCompile(`"a": "32"`),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Session.Post() error = %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.want.MatchString(got.DContent) == false {
|
||||||
|
t.Errorf("Session.Post() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
60
response.go
Normal file
60
response.go
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package requests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
|
"compress/zlib"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Response 响应内容包含http.Response
|
||||||
|
type Response struct {
|
||||||
|
DContent string
|
||||||
|
GResponse *http.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromHTTPResponse 生成Response 从标准http.Response
|
||||||
|
func FromHTTPResponse(resp *http.Response) (*Response, error) {
|
||||||
|
|
||||||
|
// 复制response 返回内容 并且测试是否有解压的需求
|
||||||
|
srcbuf, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
resp.Body.Close()
|
||||||
|
|
||||||
|
cbuf := bytes.NewBuffer([]byte{})
|
||||||
|
_, err = io.Copy(cbuf, bytes.NewReader(srcbuf))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Body = ioutil.NopCloser(cbuf)
|
||||||
|
|
||||||
|
content := string(srcbuf)
|
||||||
|
srcReader := bytes.NewReader(srcbuf)
|
||||||
|
|
||||||
|
if r, err := gzip.NewReader(srcReader); err == nil {
|
||||||
|
buf, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
content = string(buf)
|
||||||
|
} else if r, err := zlib.NewReader(srcReader); err == nil {
|
||||||
|
buf, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
content = string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Response{DContent: content, GResponse: resp}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content 返回解压后的内容
|
||||||
|
func (gresp *Response) Content() string {
|
||||||
|
return gresp.DContent
|
||||||
|
}
|
1
response_test.go
Normal file
1
response_test.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package requests
|
BIN
tests/file.js
Normal file
BIN
tests/file.js
Normal file
Binary file not shown.
2
tests/json.file
Normal file
2
tests/json.file
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
json.file
|
||||||
|
fdsfsdavxvxwewe32323412jsonjsonjsonjson
|
2
tests/learn.js
Normal file
2
tests/learn.js
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
learn.js
|
||||||
|
fdsfsdavxlearnlearnlearnlearn
|
58
upload_file.go
Normal file
58
upload_file.go
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package requests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UploadFile 上传文件的结构
|
||||||
|
type UploadFile struct {
|
||||||
|
FileName string
|
||||||
|
FieldName string
|
||||||
|
FileReaderCloser io.ReadCloser
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadFileFromPath 从本地文件获取上传文件
|
||||||
|
func UploadFileFromPath(fileName string) (*UploadFile, error) {
|
||||||
|
fd, err := os.Open(fileName)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &UploadFile{FileReaderCloser: fd, FileName: fileName}, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadFileFromGlob 根据Glob从本地文件获取上传文件
|
||||||
|
func UploadFileFromGlob(glob string) ([]*UploadFile, error) {
|
||||||
|
files, err := filepath.Glob(glob)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(files) == 0 {
|
||||||
|
log.Println("UploadFileFromGlob: len(files) == 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
var ufiles []*UploadFile
|
||||||
|
|
||||||
|
for _, f := range files {
|
||||||
|
if s, err := os.Stat(f); err != nil || s.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fd, err := os.Open(f)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(fd.Name(), err)
|
||||||
|
} else {
|
||||||
|
ufiles = append(ufiles, &UploadFile{FileReaderCloser: fd, FileName: filepath.Base(fd.Name())})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ufiles, nil
|
||||||
|
|
||||||
|
}
|
71
workflow.go
Normal file
71
workflow.go
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
package requests
|
||||||
|
|
||||||
|
import "net/url"
|
||||||
|
|
||||||
|
// Workflow 工作流
|
||||||
|
type Workflow struct {
|
||||||
|
session *Session
|
||||||
|
URL string
|
||||||
|
Method string
|
||||||
|
Body *Params
|
||||||
|
Query map[string][]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWorkflow new and init workflow
|
||||||
|
func NewWorkflow(ses *Session) *Workflow {
|
||||||
|
wf := &Workflow{}
|
||||||
|
wf.SwitchSession(ses)
|
||||||
|
return wf
|
||||||
|
}
|
||||||
|
|
||||||
|
// SwitchSession 替换Session
|
||||||
|
func (wf *Workflow) SwitchSession(ses *Session) {
|
||||||
|
wf.session = ses
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetParams 参数设置
|
||||||
|
func (wf *Workflow) SetParams(params ...interface{}) *Workflow {
|
||||||
|
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.Body = []byte(values.Encode())
|
||||||
|
case map[string][]string:
|
||||||
|
values = param
|
||||||
|
wf.Body.Body = []byte(values.Encode())
|
||||||
|
case string:
|
||||||
|
wf.Body.Body = []byte(param)
|
||||||
|
case []byte:
|
||||||
|
wf.Body.Body = param
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wf
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute 执行
|
||||||
|
func (wf *Workflow) Execute() (*Response, error) {
|
||||||
|
req := buildBodyRequest(wf.Method, wf.URL, wf.Body)
|
||||||
|
resp, err := wf.session.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return FromHTTPResponse(resp)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user