Repository: cloudwego/hertz
Pull request #776 (2023-05-11 13:20:12)

feat: add MIME consts
#### What type of PR is this?
<!--
Add one of the following kinds:

build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
docs: Documentation only changes
feat: A new feature
optimize: A new optimization
fix: A bug fix
perf: A code change that improves performance
refactor: A code change that neither fixes a bug nor adds a feature
style: Changes that do not affect the meaning of the code (white space, formatting, missing semi-colons, etc)
test: Adding missing tests or correcting existing tests
chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
-->
feat
#### Check the PR title.
<!--
The description of the title will be attached in Release Notes, 
so please describe it from user-oriented, what this PR does / why we need it.
Please check your PR title with the below requirements:
-->
- [x] This PR title match the format: `<type>(optional scope): <description>`.
- [x] The description of this PR title is user-oriented and clear enough for others to understand.
- [ ] Attach the PR updating the user documentation if the current PR requires user awareness at the usage level. [User docs repo](https://github.com/cloudwego/cloudwego.github.io).

#### (Optional) Translate the PR title into Chinese.
新增 MIME 常量

#### (Optional) More detail description for this PR(en: English/zh: Chinese).
<!--
Provide more detailed info for review. If it is a perf type PR, perf data is suggested to give.
-->
en: add MIME consts
zh(optional): 新增 MIME 常量

#### (Optional) Which issue(s) this PR fixes:
<!--
Automatically closes linked issue when PR is merged.
Eg: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->
#754 
#### (Optional) The PR that updates user documentation:
<!--
If the current PR requires user awareness at the usage level, please submit a PR to update user docs. [User docs repo](https://github.com/cloudwego/cloudwego.github.io)
-->



cqqqq777: just add some commonly used MIME types
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/cloudwego/hertz/pull/776?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego) Report
Patch coverage has no change and project coverage change: **`-0.08`** :warning:
> Comparison is base [(`0b9dfea`)](https://app.codecov.io/gh/cloudwego/hertz/commit/0b9dfea97dd7fb40319adec65f553dbb0a5d086c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego) 75.66% compared to head [(`ec65aef`)](https://app.codecov.io/gh/cloudwego/hertz/pull/776?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego) 75.59%.

> :exclamation: Current head ec65aef differs from pull request most recent head 0b39174. Consider uploading reports for the commit 0b39174 to get more accurate results

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##           develop     #776      +/-   ##
===========================================
- Coverage    75.66%   75.59%   -0.08%     
===========================================
  Files           97       97              
  Lines         9477     9477              
===========================================
- Hits          7171     7164       -7     
- Misses        1856     1862       +6     
- Partials       450      451       +1     
```


[see 1 file with indirect coverage changes](https://app.codecov.io/gh/cloudwego/hertz/pull/776/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego)


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/cloudwego/hertz/pull/776?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego).

welkeyever: Please follow the pr template and complete the information.
Like this: #758 
FGYFFFF: @cqqqq777 The unit test seems to have some MIME content-type strings, would you like to help replace them together?
cqqqq777: ok, I need some time.
cqqqq777: ok
li-jin-gou: @cqqqq777  This is great and is what users need right now. But can we provide a document like fiber to help users know that we provide these constants. refer to https://docs.gofiber.io/api/constants .

Patch:
diff --git a/pkg/protocol/consts/headers.go b/pkg/protocol/consts/headers.go
index d01af5a..3c2b82e 100644
--- a/pkg/protocol/consts/headers.go
+++ b/pkg/protocol/consts/headers.go
@@ -85,4 +85,79 @@ const (
 	HTTP11 = "HTTP/1.1"
 	HTTP10 = "HTTP/1.0"
 	HTTP20 = "HTTP/2.0"
+
+	// MIME text
+	MIMETextPlain             = "text/plain"
+	MIMETextPlainUTF8         = "text/plain; charset=utf-8"
+	MIMETextPlainISO88591     = "text/plain; charset=iso-8859-1"
+	MIMETextPlainFormatFlowed = "text/plain; format=flowed"
+	MIMETextPlainDelSpaceYes  = "text/plain; delsp=yes"
+	MiMETextPlainDelSpaceNo   = "text/plain; delsp=no"
+	MIMETextHtml              = "text/html"
+	MIMETextCss               = "text/css"
+	MIMETextJavascript        = "text/javascript"
+
+	// MIME application
+	MIMEApplicationOctetStream  = "application/octet-stream"
+	MIMEApplicationFlash        = "application/x-shockwave-flash"
+	MIMEApplicationHTMLForm     = "application/x-www-form-urlencoded"
+	MIMEApplicationHTMLFormUTF8 = "application/x-www-form-urlencoded; charset=UTF-8"
+	MIMEApplicationTar          = "application/x-tar"
+	MIMEApplicationGZip         = "application/gzip"
+	MIMEApplicationXGZip        = "application/x-gzip"
+	MIMEApplicationBZip2        = "application/bzip2"
+	MIMEApplicationXBZip2       = "application/x-bzip2"
+	MIMEApplicationShell        = "application/x-sh"
+	MIMEApplicationDownload     = "application/x-msdownload"
+	MIMEApplicationJSON         = "application/json"
+	MIMEApplicationJSONUTF8     = "application/json; charset=utf-8"
+	MIMEApplicationXML          = "application/xml"
+	MIMEApplicationXMLUTF8      = "application/xml; charset=utf-8"
+	MIMEApplicationZip          = "application/zip"
+	MIMEApplicationPdf          = "application/pdf"
+	MIMEApplicationWord         = "application/msword"
+	MIMEApplicationExcel        = "application/vnd.ms-excel"
+	MIMEApplicationPPT          = "application/vnd.ms-powerpoint"
+	MIMEApplicationOpenXMLWord  = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+	MIMEApplicationOpenXMLExcel = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+	MIMEApplicationOpenXMLPPT   = "application/vnd.openxmlformats-officedocument.presentationml.presentation"
+
+	// MIME image
+	MIMEImageJPEG         = "image/jpeg"
+	MIMEImagePNG          = "image/png"
+	MIMEImageGIF          = "image/gif"
+	MIMEImageBitmap       = "image/bmp"
+	MIMEImageWebP         = "image/webp"
+	MIMEImageIco          = "image/x-icon"
+	MIMEImageMicrosoftICO = "image/vnd.microsoft.icon"
+	MIMEImageTIFF         = "image/tiff"
+	MIMEImageSVG          = "image/svg+xml"
+	MIMEImagePhotoshop    = "image/vnd.adobe.photoshop"
+
+	// MIME audio
+	MIMEAudioBasic     = "audio/basic"
+	MIMEAudioL24       = "audio/L24"
+	MIMEAudioMP3       = "audio/mp3"
+	MIMEAudioMP4       = "audio/mp4"
+	MIMEAudioMPEG      = "audio/mpeg"
+	MIMEAudioOggVorbis = "audio/ogg"
+	MIMEAudioWAVE      = "audio/vnd.wave"
+	MIMEAudioWebM      = "audio/webm"
+	MIMEAudioAAC       = "audio/x-aac"
+	MIMEAudioAIFF      = "audio/x-aiff"
+	MIMEAudioMIDI      = "audio/x-midi"
+	MIMEAudioM3U       = "audio/x-mpegurl"
+	MIMEAudioRealAudio = "audio/x-pn-realaudio"
+
+	// MIME video
+	MIMEVideoMPEG          = "video/mpeg"
+	MIMEVideoOgg           = "video/ogg"
+	MIMEVideoMP4           = "video/mp4"
+	MIMEVideoQuickTime     = "video/quicktime"
+	MIMEVideoWinMediaVideo = "video/x-ms-wmv"
+	MIMEVideWebM           = "video/webm"
+	MIMEVideoFlashVideo    = "video/x-flv"
+	MIMEVideo3GPP          = "video/3gpp"
+	MIMEVideoAVI           = "video/x-msvideo"
+	MIMEVideoMatroska      = "video/x-matroska"
 )


Test patch:
diff --git a/pkg/app/client/client_test.go b/pkg/app/client/client_test.go
index 8862d84..84c6a91 100644
--- a/pkg/app/client/client_test.go
+++ b/pkg/app/client/client_test.go
@@ -975,7 +975,7 @@ func TestClientFollowRedirects(t *testing.T) {
 			u.Update("/bar")
 			ctx.Redirect(consts.StatusFound, u.FullURI())
 		default:
-			ctx.SetContentType("text/plain")
+			ctx.SetContentType(consts.MIMETextPlain)
 			ctx.Response.SetBody(ctx.Path())
 		}
 	}
@@ -1440,13 +1440,13 @@ func TestSetMultipartFields(t *testing.T) {
 		{
 			Param:       "file_1",
 			FileName:    files[0],
-			ContentType: "application/json",
+			ContentType: consts.MIMEApplicationJSON,
 			Reader:      strings.NewReader(jsonStr1),
 		},
 		{
 			Param:       "file_2",
 			FileName:    files[1],
-			ContentType: "application/json",
+			ContentType: consts.MIMEApplicationJSON,
 			Reader:      strings.NewReader(jsonStr2),
 		},
 	}
diff --git a/pkg/app/context_test.go b/pkg/app/context_test.go
index 31d6da0..7853d2a 100644
--- a/pkg/app/context_test.go
+++ b/pkg/app/context_test.go
@@ -431,7 +431,7 @@ tailfoobar`
 			t.Fatalf("unexpected filename %q. Expecting %q", v.Filename, "TODO")
 		}
 		ct := v.Header.Get("Content-Type")
-		if ct != "application/octet-stream" {
+		if ct != consts.MIMEApplicationOctetStream {
 			t.Fatalf("unexpected content-type %q. Expecting %q", ct, "application/octet-stream")
 		}
 	}
@@ -472,7 +472,7 @@ func TestContextRenderFileFromFS(t *testing.T) {
 
 	assert.DeepEqual(t, consts.StatusOK, ctx.Response.StatusCode())
 	assert.True(t, strings.Contains(resp.GetHTTP1Response(&ctx.Response).String(), "func (fs *FS) initRequestHandler() {"))
-	assert.DeepEqual(t, "text/plain; charset=utf-8", string(ctx.Response.Header.Peek("Content-Type")))
+	assert.DeepEqual(t, consts.MIMETextPlainUTF8, string(ctx.Response.Header.Peek("Content-Type")))
 	assert.DeepEqual(t, "/some/path", string(ctx.Request.URI().Path()))
 }
 
@@ -489,7 +489,7 @@ func TestContextRenderFile(t *testing.T) {
 
 	assert.DeepEqual(t, consts.StatusOK, ctx.Response.StatusCode())
 	assert.True(t, strings.Contains(resp.GetHTTP1Response(&ctx.Response).String(), "func (fs *FS) initRequestHandler() {"))
-	assert.DeepEqual(t, "text/plain; charset=utf-8", string(ctx.Response.Header.Peek("Content-Type")))
+	assert.DeepEqual(t, consts.MIMETextPlainUTF8, string(ctx.Response.Header.Peek("Content-Type")))
 }
 
 func TestContextRenderAttachment(t *testing.T) {
@@ -625,7 +625,7 @@ func TestRender(t *testing.T) {
 	c := NewContext(0)
 
 	c.Render(consts.StatusOK, &render.Data{
-		ContentType: "application/json; charset=utf-8",
+		ContentType: consts.MIMEApplicationJSONUTF8,
 		Data:        []byte("{\"test\":1}"),
 	})
 
@@ -666,8 +666,8 @@ func TestContextReset(t *testing.T) {
 
 func TestContextContentType(t *testing.T) {
 	c := NewContext(0)
-	c.Request.Header.Set("Content-Type", "application/json; charset=utf-8")
-	assert.DeepEqual(t, "application/json; charset=utf-8", bytesconv.B2s(c.ContentType()))
+	c.Request.Header.Set("Content-Type", consts.MIMEApplicationJSONUTF8)
+	assert.DeepEqual(t, consts.MIMEApplicationJSONUTF8, bytesconv.B2s(c.ContentType()))
 }
 
 func TestClientIp(t *testing.T) {
@@ -735,7 +735,7 @@ func TestGetQuery(t *testing.T) {
 
 func TestGetPostForm(t *testing.T) {
 	c := NewContext(0)
-	c.Request.Header.SetContentTypeBytes([]byte("application/x-www-form-urlencoded"))
+	c.Request.Header.SetContentTypeBytes([]byte(consts.MIMEApplicationHTMLForm))
 	c.Request.SetBodyString("a=1&b=")
 	v, exists := c.GetPostForm("b")
 	assert.DeepEqual(t, "", v)
@@ -794,7 +794,7 @@ func TestContextAbortWithStatusJSON(t *testing.T) {
 	assert.True(t, c.IsAborted())
 
 	contentType := c.Response.Header.Peek("Content-Type")
-	assert.DeepEqual(t, "application/json; charset=utf-8", string(contentType))
+	assert.DeepEqual(t, consts.MIMEApplicationJSONUTF8, string(contentType))
 
 	jsonStringBody := c.Response.Body()
 	assert.DeepEqual(t, "{\"foo\":\"fooValue\",\"bar\":\"barValue\"}", string(jsonStringBody))
@@ -803,7 +803,7 @@ func TestContextAbortWithStatusJSON(t *testing.T) {
 func TestRequestCtxFormValue(t *testing.T) {
 	ctx := NewContext(0)
 	ctx.Request.SetRequestURI("/foo/bar?baz=123&aaa=bbb")
-	ctx.Request.Header.SetContentTypeBytes([]byte("application/x-www-form-urlencoded"))
+	ctx.Request.Header.SetContentTypeBytes([]byte(consts.MIMEApplicationHTMLForm))
 	ctx.Request.SetBodyString("qqq=port&mmm=sddd")
 
 	v := ctx.FormValue("baz")
@@ -831,7 +831,7 @@ func TestRequestCtxFormValue(t *testing.T) {
 func TestSetCustomFormValueFunc(t *testing.T) {
 	ctx := NewContext(0)
 	ctx.Request.SetRequestURI("/foo/bar?aaa=bbb")
-	ctx.Request.Header.SetContentTypeBytes([]byte("application/x-www-form-urlencoded"))
+	ctx.Request.Header.SetContentTypeBytes([]byte(consts.MIMEApplicationHTMLForm))
 	ctx.Request.SetBodyString("aaa=port")
 
 	ctx.SetFormValueFunc(func(ctx *RequestContext, key string) []byte {
@@ -1154,9 +1154,9 @@ func TestReset(t *testing.T) {
 
 func TestGetHeader(t *testing.T) {
 	ctx := NewContext(0)
-	ctx.Request.Header.SetContentTypeBytes([]byte("text/plain; charset=utf-8"))
+	ctx.Request.Header.SetContentTypeBytes([]byte(consts.MIMETextPlainUTF8))
 	val := ctx.GetHeader("Content-Type")
-	assert.DeepEqual(t, "text/plain; charset=utf-8", string(val))
+	assert.DeepEqual(t, consts.MIMETextPlainUTF8, string(val))
 }
 
 func TestGetRawData(t *testing.T) {
diff --git a/pkg/app/fs_test.go b/pkg/app/fs_test.go
index 389fe9e..1cd545e 100644
--- a/pkg/app/fs_test.go
+++ b/pkg/app/fs_test.go
@@ -655,7 +655,7 @@ func TestServeFileContentType(t *testing.T) {
 		t.Fatalf("unexpected error: %s", err)
 	}
 
-	expected := []byte("image/png")
+	expected := []byte(consts.MIMEImagePNG)
 	if !bytes.Equal(r.Header.ContentType(), expected) {
 		t.Fatalf("Unexpected Content-Type, expected: %q got %q", expected, r.Header.ContentType())
 	}
diff --git a/pkg/app/server/render/render_test.go b/pkg/app/server/render/render_test.go
index bc839e0..338d151 100644
--- a/pkg/app/server/render/render_test.go
+++ b/pkg/app/server/render/render_test.go
@@ -48,6 +48,7 @@ import (
 	"github.com/bytedance/sonic"
 	"github.com/cloudwego/hertz/pkg/common/test/assert"
 	"github.com/cloudwego/hertz/pkg/protocol"
+	"github.com/cloudwego/hertz/pkg/protocol/consts"
 )
 
 type xmlmap map[string]interface{}
@@ -82,13 +83,13 @@ func TestRenderJSON(t *testing.T) {
 	}
 
 	(JSONRender{data}).WriteContentType(resp)
-	assert.DeepEqual(t, []byte("application/json; charset=utf-8"), resp.Header.Peek("Content-Type"))
+	assert.DeepEqual(t, []byte(consts.MIMEApplicationJSONUTF8), resp.Header.Peek("Content-Type"))
 
 	err := (JSONRender{data}).Render(resp)
 
 	assert.Nil(t, err)
 	assert.DeepEqual(t, []byte("{\"foo\":\"bar\",\"html\":\"\\u003cb\\u003e\"}"), resp.Body())
-	assert.DeepEqual(t, []byte("application/json; charset=utf-8"), resp.Header.Peek("Content-Type"))
+	assert.DeepEqual(t, []byte(consts.MIMEApplicationJSONUTF8), resp.Header.Peek("Content-Type"))
 }
 
 func TestRenderJSONError(t *testing.T) {
@@ -106,7 +107,7 @@ func TestRenderString(t *testing.T) {
 		Format: "hello %s %d",
 		Data:   []interface{}{},
 	}).WriteContentType(resp)
-	assert.DeepEqual(t, []byte("text/plain; charset=utf-8"), resp.Header.Peek("Content-Type"))
+	assert.DeepEqual(t, []byte(consts.MIMETextPlainUTF8), resp.Header.Peek("Content-Type"))
 
 	err := (String{
 		Format: "hola %s %d",
@@ -115,7 +116,7 @@ func TestRenderString(t *testing.T) {
 
 	assert.Nil(t, err)
 	assert.DeepEqual(t, []byte("hola manu 2"), resp.Body())
-	assert.DeepEqual(t, []byte("text/plain; charset=utf-8"), resp.Header.Peek("Content-Type"))
+	assert.DeepEqual(t, []byte(consts.MIMETextPlainUTF8), resp.Header.Peek("Content-Type"))
 }
 
 func TestRenderStringLenZero(t *testing.T) {
@@ -128,7 +129,7 @@ func TestRenderStringLenZero(t *testing.T) {
 
 	assert.Nil(t, err)
 	assert.DeepEqual(t, []byte("hola %s %d"), resp.Body())
-	assert.DeepEqual(t, []byte("text/plain; charset=utf-8"), resp.Header.Peek("Content-Type"))
+	assert.DeepEqual(t, []byte(consts.MIMETextPlainUTF8), resp.Header.Peek("Content-Type"))
 }
 
 func TestRenderData(t *testing.T) {
@@ -142,7 +143,7 @@ func TestRenderData(t *testing.T) {
 
 	assert.Nil(t, err)
 	assert.DeepEqual(t, []byte("#!PNG some raw data"), resp.Body())
-	assert.DeepEqual(t, []byte("image/png"), resp.Header.Peek("Content-Type"))
+	assert.DeepEqual(t, []byte(consts.MIMEImagePNG), resp.Header.Peek("Content-Type"))
 }
 
 func TestRenderXML(t *testing.T) {
@@ -152,13 +153,13 @@ func TestRenderXML(t *testing.T) {
 	}
 
 	(XML{data}).WriteContentType(resp)
-	assert.DeepEqual(t, []byte("application/xml; charset=utf-8"), resp.Header.Peek("Content-Type"))
+	assert.DeepEqual(t, []byte(consts.MIMEApplicationXMLUTF8), resp.Header.Peek("Content-Type"))
 
 	err := (XML{data}).Render(resp)
 
 	assert.Nil(t, err)
 	assert.DeepEqual(t, []byte("<map><foo>bar</foo></map>"), resp.Body())
-	assert.DeepEqual(t, []byte("application/xml; charset=utf-8"), resp.Header.Peek("Content-Type"))
+	assert.DeepEqual(t, []byte(consts.MIMEApplicationXMLUTF8), resp.Header.Peek("Content-Type"))
 }
 
 func TestRenderIndentedJSON(t *testing.T) {
@@ -169,7 +170,7 @@ func TestRenderIndentedJSON(t *testing.T) {
 	t.Run("TestHeader", func(t *testing.T) {
 		resp := &protocol.Response{}
 		(IndentedJSON{data}).WriteContentType(resp)
-		assert.DeepEqual(t, []byte("application/json; charset=utf-8"), resp.Header.Peek("Content-Type"))
+		assert.DeepEqual(t, []byte(consts.MIMEApplicationJSONUTF8), resp.Header.Peek("Content-Type"))
 	})
 	t.Run("TestBody", func(t *testing.T) {
 		ResetStdJSONMarshal()
@@ -177,7 +178,7 @@ func TestRenderIndentedJSON(t *testing.T) {
 		err := (IndentedJSON{data}).Render(resp)
 		assert.Nil(t, err)
 		assert.DeepEqual(t, []byte("{\n    \"foo\": \"bar\",\n    \"html\": \"h1\"\n}"), resp.Body())
-		assert.DeepEqual(t, []byte("application/json; charset=utf-8"), resp.Header.Peek("Content-Type"))
+		assert.DeepEqual(t, []byte(consts.MIMEApplicationJSONUTF8), resp.Header.Peek("Content-Type"))
 		ResetJSONMarshal(sonic.Marshal)
 	})
 	t.Run("TestError", func(t *testing.T) {
diff --git a/pkg/protocol/http1/req/request_test.go b/pkg/protocol/http1/req/request_test.go
index a0a29de..e123da4 100644
--- a/pkg/protocol/http1/req/request_test.go
+++ b/pkg/protocol/http1/req/request_test.go
@@ -532,7 +532,7 @@ func TestRequestHostFromHeader(t *testing.T) {
 func TestRequestContentTypeWithCharset(t *testing.T) {
 	t.Parallel()
 
-	expectedContentType := "application/x-www-form-urlencoded; charset=UTF-8"
+	expectedContentType := consts.MIMEApplicationHTMLFormUTF8
 	expectedBody := "0123=56789"
 	s := fmt.Sprintf("POST / HTTP/1.1\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\n%s",
 		expectedContentType, len(expectedBody), expectedBody)
diff --git a/pkg/protocol/request_test.go b/pkg/protocol/request_test.go
index 0f52686..fda96cd 100644
--- a/pkg/protocol/request_test.go
+++ b/pkg/protocol/request_test.go
@@ -56,6 +56,7 @@ import (
 	"github.com/cloudwego/hertz/pkg/common/compress"
 	"github.com/cloudwego/hertz/pkg/common/config"
 	"github.com/cloudwego/hertz/pkg/common/test/assert"
+	"github.com/cloudwego/hertz/pkg/protocol/consts"
 )
 
 type errorReader struct{}
@@ -369,7 +370,7 @@ func TestRequestSetFormData(t *testing.T) {
 	assert.DeepEqual(t, "username", string(r.postArgs.args[0].key))
 	assert.DeepEqual(t, "admin", string(r.postArgs.args[0].value))
 	assert.DeepEqual(t, true, r.parsedPostArgs)
-	assert.DeepEqual(t, "application/x-www-form-urlencoded", string(r.Header.contentType))
+	assert.DeepEqual(t, consts.MIMEApplicationHTMLForm, string(r.Header.contentType))
 
 	r = &Request{}
 	value := map[string][]string{"item": {"apple", "peach"}}
@@ -573,7 +574,7 @@ func TestRequestPostArgs(t *testing.T) {
 	mr := strings.NewReader(s)
 	r := &Request{}
 	r.SetBodyStream(mr, len(s))
-	r.Header.contentType = []byte("application/x-www-form-urlencoded")
+	r.Header.contentType = []byte(consts.MIMEApplicationHTMLForm)
 	arg := r.PostArgs()
 	assert.DeepEqual(t, "username", string(arg.args[0].key))
 	assert.DeepEqual(t, "admin", string(arg.args[0].value))