From 02bc589ba35bf7795ba8dbc455670e5c89683f1b Mon Sep 17 00:00:00 2001
From: huangsimin <huangsimin@youmi.net>
Date: Mon, 19 Nov 2018 18:07:37 +0800
Subject: [PATCH] add code to http://474420502.top/eson/requests.git

---
 base.go         | 17 ++++++-------
 multipart.go    |  6 ++---
 session.go      | 64 +++++++++++++++++++++++++++++++++++++++++++++----
 session_test.go |  2 +-
 workflow.go     | 16 ++++++-------
 5 files changed, 79 insertions(+), 26 deletions(-)

diff --git a/base.go b/base.go
index 74f8532..0629d00 100644
--- a/base.go
+++ b/base.go
@@ -12,15 +12,15 @@ func buildBodyRequest(wf *Workflow) *http.Request {
 	var err error
 	contentType := ""
 
-	if wf.Body.IOBody == nil {
+	if wf.Body.IOBody() == nil {
 		req, err = http.NewRequest(wf.Method, wf.GetStringURL(), nil)
 	} else {
 		var bodybuf *bytes.Buffer
-		switch wf.Body.IOBody.(type) {
+		switch wf.Body.IOBody().(type) {
 		case []byte:
-			bodybuf = bytes.NewBuffer(wf.Body.IOBody.([]byte))
+			bodybuf = bytes.NewBuffer(wf.Body.IOBody().([]byte))
 		case *bytes.Buffer:
-			bodybuf = bytes.NewBuffer(wf.Body.IOBody.(*bytes.Buffer).Bytes())
+			bodybuf = bytes.NewBuffer(wf.Body.IOBody().(*bytes.Buffer).Bytes())
 		default:
 			panic(errors.New("the type is not exist, type is" + reflect.TypeOf(wf.Body.IOBody).String()))
 		}
@@ -31,13 +31,10 @@ func buildBodyRequest(wf *Workflow) *http.Request {
 		panic(err)
 	}
 
-	if wf.Body.ContentType != "" {
-		if wf.Body.ContentType == TypeContentEmpty {
-			contentType = ""
-		} else {
-			contentType = wf.Body.ContentType
-		}
+	if wf.Body.ContentType() != "" {
+		contentType = wf.Body.ContentType()
 	} else {
+		contentType = ""
 		if contentType == "" {
 			if wf.Method == "POST" || wf.Method == "PUT" || wf.Method == "PATCH" {
 				contentType = TypeURLENCODED
diff --git a/multipart.go b/multipart.go
index 27fb473..64162c7 100644
--- a/multipart.go
+++ b/multipart.go
@@ -17,7 +17,7 @@ func writeFormUploadFile(mwriter *multipart.Writer, ufile *UploadFile) {
 	io.Copy(part, ufile.FileReaderCloser)
 }
 
-func createMultipart(postParams *Body, params []interface{}) {
+func createMultipart(postParams IBody, params []interface{}) {
 	plen := len(params)
 
 	body := &bytes.Buffer{}
@@ -85,6 +85,6 @@ func createMultipart(postParams *Body, params []interface{}) {
 		}
 	}
 
-	postParams.ContentType = mwriter.FormDataContentType()
-	postParams.IOBody = body
+	postParams.AddContentType(mwriter.FormDataContentType())
+	postParams.SetIOBody(body)
 }
diff --git a/session.go b/session.go
index 0f59278..546f969 100644
--- a/session.go
+++ b/session.go
@@ -8,6 +8,7 @@ import (
 	"net/url"
 	"reflect"
 	"runtime"
+	"strings"
 	"time"
 
 	"golang.org/x/net/publicsuffix"
@@ -16,9 +17,59 @@ import (
 // Body 相关参数结构
 type Body struct {
 	// Query       map[string][]string
-	IOBody interface{}
+	ioBody interface{}
 	// Files       []UploadFile
-	ContentType string
+	contentTypes map[string]int
+}
+
+// NewBody new body pointer
+func NewBody() *Body {
+	b := &Body{}
+	b.contentTypes = make(map[string]int)
+	return b
+}
+
+// SetIOBody 设置IOBody的值
+func (body *Body) SetIOBody(iobody interface{}) {
+	body.ioBody = iobody
+}
+
+// IOBody 获取ioBody值
+func (body *Body) IOBody() interface{} {
+	return body.ioBody
+}
+
+// ContentType 获取ContentType
+func (body *Body) ContentType() string {
+	content := ""
+	for kvalue := range body.contentTypes {
+		content += kvalue + ";"
+	}
+	return strings.TrimRight(content, ";")
+}
+
+// AddContentType 添加 Add Type类型
+func (body *Body) AddContentType(ct string) {
+	for _, v := range strings.Split(ct, ";") {
+		v = strings.Trim(v, " ")
+		if v != "" {
+			body.contentTypes[v] = 1
+		}
+	}
+
+}
+
+// IBody 相关参数结构
+type IBody interface {
+
+	// Query       map[string][]string
+	IOBody() interface{}
+	// SetIOBody
+	SetIOBody(iobody interface{})
+	// Files       []UploadFile
+	ContentType() string
+	// AppendContent
+	AddContentType(ct string)
 }
 
 // BasicAuth 帐号认真结构
@@ -34,7 +85,7 @@ type Session struct {
 	client    *http.Client
 	transport *http.Transport
 	cookiejar http.CookieJar
-	body      *Body
+	body      IBody
 	auth      *BasicAuth
 
 	Header http.Header
@@ -46,6 +97,10 @@ const (
 	TypeJSON = "application/json"
 	// TypeXML 类型
 	TypeXML = "text/xml"
+	// TypePlain 类型
+	TypePlain = "text/plain"
+	// TypeHTML 类型
+	TypeHTML = "text/html"
 	// TypeURLENCODED 类型
 	TypeURLENCODED = "application/x-www-form-urlencoded"
 	// TypeForm PostForm类型
@@ -54,6 +109,7 @@ const (
 	TypeContentEmpty = "ContentEmpty"
 	// TypeFormData 类型
 	TypeFormData = "multipart/form-data"
+
 	// HeaderKeyHost Host
 	HeaderKeyHost = "Host"
 	// HeaderKeyUA User-Agent
@@ -101,7 +157,7 @@ func NewSession() *Session {
 	}
 
 	client.Jar = cjar
-	return &Session{client: client, body: &Body{}, transport: transport, auth: nil, cookiejar: client.Jar, Header: make(http.Header)}
+	return &Session{client: client, body: NewBody(), transport: transport, auth: nil, cookiejar: client.Jar, Header: make(http.Header)}
 }
 
 // SetConfig 设置配置
diff --git a/session_test.go b/session_test.go
index 00a02db..1911aa6 100644
--- a/session_test.go
+++ b/session_test.go
@@ -118,7 +118,7 @@ func TestSession_Setparams(t *testing.T) {
 		},
 		{
 			name:   "test xml",
-			fields: fields{client: &http.Client{}, params: &Body{}},
+			fields: fields{client: &http.Client{}, params: NewBody()},
 			args:   args{params: []interface{}{`<request><parameters><password>test</password></parameters></request>`, TypeXML}},
 			want:   regexp.MustCompile(`"data": "<request><parameters><password>test</password></parameters></request>"`),
 		},
diff --git a/workflow.go b/workflow.go
index f557459..bd5da11 100644
--- a/workflow.go
+++ b/workflow.go
@@ -12,7 +12,7 @@ type Workflow struct {
 	session   *Session
 	ParsedURL *url.URL
 	Method    string
-	Body      *Body
+	Body      IBody
 	Header    http.Header
 	Cookies   map[string]*http.Cookie
 }
@@ -24,7 +24,7 @@ func NewWorkflow(ses *Session, u string) *Workflow {
 
 	wf.SetURL(u)
 
-	wf.Body = &Body{}
+	wf.Body = NewBody()
 	wf.Header = make(http.Header)
 	wf.Cookies = make(map[string]*http.Cookie)
 	return wf
@@ -183,9 +183,9 @@ func (wf *Workflow) SetBody(params ...interface{}) *Workflow {
 		if plen >= 2 {
 			t := params[plen-1]
 			defaultContentType = t.(string)
-			wf.Body.ContentType = defaultContentType
+			wf.Body.AddContentType(defaultContentType)
 		} else {
-			wf.Body.ContentType = defaultContentType
+			wf.Body.AddContentType(defaultContentType)
 		}
 
 		if defaultContentType == TypeFormData {
@@ -199,14 +199,14 @@ func (wf *Workflow) SetBody(params ...interface{}) *Workflow {
 				for k, v := range param {
 					values.Set(k, v)
 				}
-				wf.Body.IOBody = []byte(values.Encode())
+				wf.Body.SetIOBody([]byte(values.Encode()))
 			case map[string][]string:
 				values = param
-				wf.Body.IOBody = []byte(values.Encode())
+				wf.Body.SetIOBody([]byte(values.Encode()))
 			case string:
-				wf.Body.IOBody = []byte(param)
+				wf.Body.SetIOBody([]byte(param))
 			case []byte:
-				wf.Body.IOBody = param
+				wf.Body.SetIOBody(param)
 			}
 
 		}