diff --git a/base.go b/base.go
index ea243e9..a49e3ab 100644
--- a/base.go
+++ b/base.go
@@ -37,10 +37,8 @@ func buildBodyRequest(wf *Workflow) *http.Request {
 		contentType = wf.Body.ContentType()
 	} else {
 		contentType = ""
-		if contentType == "" {
-			if wf.Method == "POST" || wf.Method == "PUT" || wf.Method == "PATCH" {
-				contentType = TypeURLENCODED
-			}
+		if wf.Method == "POST" || wf.Method == "PUT" || wf.Method == "PATCH" {
+			contentType = TypeURLENCODED
 		}
 	}
 
diff --git a/response.go b/response.go
index df4e0a6..fcc9363 100644
--- a/response.go
+++ b/response.go
@@ -27,7 +27,7 @@ func FromHTTPResponse(resp *http.Response, isDecompressNoAccept bool) (*Response
 
 	content := ""
 
-	if isDecompressNoAccept {
+	if isDecompressNoAccept { // 在某个已经遗忘的网页测试过, 为了兼容 Python requests
 		srcReader := bytes.NewReader(srcbuf)
 		var reader io.ReadCloser
 		if reader, err = gzip.NewReader(srcReader); err == nil {
diff --git a/session.go b/session.go
index 855d324..eebb3ae 100644
--- a/session.go
+++ b/session.go
@@ -78,7 +78,7 @@ type IBody interface {
 	ContentType() string
 	// AppendContent
 	AddContentType(ct string)
-	// SetPrefix 设置 Prefix;  唯一前缀
+	// SetPrefix 设置 Prefix;  唯一前缀; 就是ContentType的第一个, ContentType(Prefix);ContentType;ContentType
 	SetPrefix(ct string)
 }
 
@@ -140,6 +140,9 @@ const (
 	// TypeMixed Mixed类型
 	TypeMixed = "multipart/mixed"
 
+	// TypeUploadFile 类型 Upload File 支持path(string) 自动转换成UploadFile
+	TypeUploadFile = "uploadfile/form-data"
+
 	// HeaderKeyHost Host
 	HeaderKeyHost = "Host"
 
diff --git a/session_test.go b/session_test.go
index 6cd2e4a..2a3c3fb 100644
--- a/session_test.go
+++ b/session_test.go
@@ -169,7 +169,7 @@ func TestSession_PostUploadFile(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			ses := NewSession()
-			got, err := ses.Post("http://httpbin.org/post").SetBodyAuto(tt.args.params, TypeFormData).Execute()
+			got, err := ses.Post("http://httpbin.org/post").SetBodyAuto(tt.args.params, TypeUploadFile).Execute()
 
 			if err != nil {
 				t.Errorf("Metchod error = %v", err)
@@ -213,7 +213,7 @@ func TestSession_Put(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			ses := NewSession()
-			got, err := ses.Put("http://httpbin.org/put").SetBodyAuto(tt.args.params, TypeFormData).Execute()
+			got, err := ses.Put("http://httpbin.org/put").SetBodyAuto(tt.args.params, TypeUploadFile).Execute()
 
 			if err != nil {
 				t.Errorf("Metchod error = %v", err)
@@ -257,7 +257,7 @@ func TestSession_Patch(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			ses := NewSession()
-			got, err := ses.Patch("http://httpbin.org/patch").SetBodyAuto(tt.args.params, TypeFormData).Execute()
+			got, err := ses.Patch("http://httpbin.org/patch").SetBodyAuto(tt.args.params, TypeUploadFile).Execute()
 
 			if err != nil {
 				t.Errorf("Metchod error = %v", err)
diff --git a/upload_file_test.go b/upload_file_test.go
new file mode 100644
index 0000000..a7f4bbe
--- /dev/null
+++ b/upload_file_test.go
@@ -0,0 +1,28 @@
+package requests
+
+import (
+	"testing"
+
+	"474420502.top/eson/gjson"
+)
+
+func TestUploadFile(t *testing.T) {
+	ses := NewSession()
+	wf := ses.Put("http://httpbin.org/put")
+
+	ufile, err := UploadFileFromPath("go.mod")
+	if err != nil {
+		t.Error(err)
+	}
+	wf.SetBodyAuto(ufile, TypeUploadFile)
+	resp, _ := wf.Execute()
+	if _, ok := gjson.Get(resp.Content(), "files").Map()["file0"]; !ok {
+		t.Error("file error", resp.Content())
+	}
+
+	wf.SetBodyAuto("go.mod", TypeUploadFile)
+	resp, _ = wf.Execute()
+	if _, ok := gjson.Get(resp.Content(), "files").Map()["file0"]; !ok {
+		t.Error("file error", resp.Content())
+	}
+}
diff --git a/workflow.go b/workflow.go
index 8e71097..33da19e 100644
--- a/workflow.go
+++ b/workflow.go
@@ -161,7 +161,7 @@ func (wf *Workflow) SetQuery(query url.Values) *Workflow {
 
 var regexGetPath = regexp.MustCompile("/[^/]*")
 
-// GetURLPath 获取Path参数
+// GetURLPath 获取Path参数 http://localhost/anything/user/pwd return [/anything /user /pwd]
 func (wf *Workflow) GetURLPath() []string {
 	return regexGetPath.FindAllString(wf.ParsedURL.Path, -1)
 }
@@ -194,7 +194,11 @@ func (wf *Workflow) GetURLRawPath() string {
 
 // SetURLRawPath 设置 参数 eg. /get = http:// hostname + /get
 func (wf *Workflow) SetURLRawPath(path string) *Workflow {
-	wf.ParsedURL.Path = path
+	if path[0] != '/' {
+		wf.ParsedURL.Path = "/" + path
+	} else {
+		wf.ParsedURL.Path = path
+	}
 	return wf
 }
 
@@ -205,7 +209,7 @@ func (wf *Workflow) SetBody(body IBody) *Workflow {
 }
 
 // GetBody 参数设置
-func (wf *Workflow) GetBody(body IBody) IBody {
+func (wf *Workflow) GetBody() IBody {
 	return wf.Body
 }
 
@@ -221,11 +225,16 @@ func (wf *Workflow) SetBodyAuto(params ...interface{}) *Workflow {
 			defaultContentType = t.(string)
 		}
 
-		wf.Body.SetPrefix(defaultContentType)
-
-		if defaultContentType == TypeFormData {
-			createMultipart(wf.Body, params)
+		if defaultContentType == TypeUploadFile {
+			wf.Body.SetPrefix(TypeFormData)
 		} else {
+			wf.Body.SetPrefix(defaultContentType)
+		}
+
+		switch defaultContentType {
+		case TypeUploadFile:
+			createMultipart(wf.Body, params) // 还存在 Mixed的可能
+		default:
 			var values url.Values
 			switch param := params[0].(type) {
 			case map[string]string:
@@ -242,8 +251,8 @@ func (wf *Workflow) SetBodyAuto(params ...interface{}) *Workflow {
 			case []byte:
 				wf.Body.SetIOBody(param)
 			}
-
 		}
+
 	}
 	return wf
 }
diff --git a/workflow_test.go b/workflow_test.go
index a07a68a..02ebf2f 100644
--- a/workflow_test.go
+++ b/workflow_test.go
@@ -4,6 +4,7 @@ import (
 	"net/http"
 	"net/url"
 	"regexp"
+	"sort"
 	"testing"
 
 	"474420502.top/eson/gjson"
@@ -202,4 +203,98 @@ func TestWorkflow_URL(t *testing.T) {
 	if wf.GetURLRawPath() != "/get" {
 		t.Error("SetParsedURL ", resp.Content())
 	}
+
+	resp, _ = wf.SetURLRawPath("anything/user/password").Execute()
+	if gjson.Get(resp.Content(), "url").String() != "http://httpbin.org/anything/user/password" {
+		t.Error("SetParsedURL ", resp.Content())
+	}
+	paths := wf.GetURLPath()
+	if paths[0] != "/anything" || paths[1] != "/user" || paths[2] != "/password" {
+		t.Error("wf.GetURLPath()", paths)
+	}
+}
+
+func TestWorkflow_Query(t *testing.T) {
+	ses := NewSession()
+	query := make(url.Values)
+	query["session"] = []string{"true"}
+	ses.SetQuery(query)
+	wf := ses.Get("http://httpbin.org/get")
+	wfquery := make(url.Values)
+	wfquery["workflow"] = []string{"do", "to"}
+	wf.SetQuery(wfquery)
+
+	resp, _ := wf.Execute()
+	result := gjson.Get(resp.Content(), "args.workflow")
+
+	for _, r := range result.Array() {
+		if !(r.String() == "to" || r.String() == "do") {
+			t.Error("workflow SetQuery error")
+		}
+	}
+
+	if gjson.Get(resp.Content(), "args.session").String() != "true" {
+		t.Error("session SetQuery error")
+	}
+
+	if v, ok := wf.GetQuery()["workflow"]; ok {
+		sort.Slice(v, func(i, j int) bool {
+			if v[i] > v[j] {
+				return true
+			}
+			return false
+		})
+		if !(v[0] == "to" && v[1] == "do") && len(v) != 2 {
+			t.Error("workflow GetQuery", v)
+		}
+	}
+
+	if v, ok := wf.GetQuery()["session"]; ok {
+		if v[0] != "true" && len(v) != 1 {
+			t.Error("workflow error")
+		}
+	}
+}
+
+func TestWorkflow_Body(t *testing.T) {
+	ses := NewSession()
+	wf := ses.Post("http://httpbin.org/post")
+	body := NewBody()
+	body.SetIOBody("a=1&b=2")
+	wf.SetBody(body)
+	resp, _ := wf.Execute()
+	form := gjson.Get(resp.Content(), "form").Map()
+	if v, ok := form["a"]; ok {
+		if v.String() != "1" {
+			t.Error(v)
+		}
+	}
+
+	if v, ok := form["b"]; ok {
+		if v.String() != "2" {
+			t.Error(v)
+		}
+	}
+
+	body.SetPrefix(TypeJSON)
+	body.SetIOBody(`{"a": "1",   "b":  "2"}`)
+	wf.SetBody(body)
+	resp, _ = wf.Execute()
+	json := gjson.Get(resp.Content(), "json").Map()
+	if v, ok := json["a"]; ok {
+		if v.String() != "1" {
+			t.Error(v)
+		}
+	}
+
+	if v, ok := json["b"]; ok {
+		if v.String() != "2" {
+			t.Error(v)
+		}
+	}
+
+	// body.SetPrefix(TypeXML)
+	// body.SetIOBody(`<root><a>1</a><b>2</b></root>`)
+	// wf.SetBody(body)
+	// resp, _ = wf.Execute()
 }