Merge pull request #775 from gin-gonic/upload
Support upload single or multiple files.
This commit is contained in:
		
							
								
								
									
										20
									
								
								context.go
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								context.go
									
									
									
									
									
								
							@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"math"
 | 
						"math"
 | 
				
			||||||
 | 
						"mime/multipart"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
@ -30,7 +31,10 @@ const (
 | 
				
			|||||||
	MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm
 | 
						MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const abortIndex int8 = math.MaxInt8 / 2
 | 
					const (
 | 
				
			||||||
 | 
						defaultMemory      = 32 << 20 // 32 MB
 | 
				
			||||||
 | 
						abortIndex    int8 = math.MaxInt8 / 2
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Context is the most important part of gin. It allows us to pass variables between middleware,
 | 
					// Context is the most important part of gin. It allows us to pass variables between middleware,
 | 
				
			||||||
// manage the flow, validate the JSON of a request and render a JSON response for example.
 | 
					// manage the flow, validate the JSON of a request and render a JSON response for example.
 | 
				
			||||||
@ -291,7 +295,7 @@ func (c *Context) PostFormArray(key string) []string {
 | 
				
			|||||||
func (c *Context) GetPostFormArray(key string) ([]string, bool) {
 | 
					func (c *Context) GetPostFormArray(key string) ([]string, bool) {
 | 
				
			||||||
	req := c.Request
 | 
						req := c.Request
 | 
				
			||||||
	req.ParseForm()
 | 
						req.ParseForm()
 | 
				
			||||||
	req.ParseMultipartForm(32 << 20) // 32 MB
 | 
						req.ParseMultipartForm(defaultMemory)
 | 
				
			||||||
	if values := req.PostForm[key]; len(values) > 0 {
 | 
						if values := req.PostForm[key]; len(values) > 0 {
 | 
				
			||||||
		return values, true
 | 
							return values, true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -303,6 +307,18 @@ func (c *Context) GetPostFormArray(key string) ([]string, bool) {
 | 
				
			|||||||
	return []string{}, false
 | 
						return []string{}, false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FormFile returns the first file for the provided form key.
 | 
				
			||||||
 | 
					func (c *Context) FormFile(name string) (*multipart.FileHeader, error) {
 | 
				
			||||||
 | 
						_, fh, err := c.Request.FormFile(name)
 | 
				
			||||||
 | 
						return fh, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MultipartForm is the parsed multipart form, including file uploads.
 | 
				
			||||||
 | 
					func (c *Context) MultipartForm() (*multipart.Form, error) {
 | 
				
			||||||
 | 
						err := c.Request.ParseMultipartForm(defaultMemory)
 | 
				
			||||||
 | 
						return c.Request.MultipartForm, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Bind checks the Content-Type to select a binding engine automatically,
 | 
					// Bind checks the Content-Type to select a binding engine automatically,
 | 
				
			||||||
// Depending the "Content-Type" header different bindings are used:
 | 
					// Depending the "Content-Type" header different bindings are used:
 | 
				
			||||||
// 		"application/json" --> JSON binding
 | 
					// 		"application/json" --> JSON binding
 | 
				
			||||||
 | 
				
			|||||||
@ -53,6 +53,37 @@ func must(err error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestContextFormFile(t *testing.T) {
 | 
				
			||||||
 | 
						buf := new(bytes.Buffer)
 | 
				
			||||||
 | 
						mw := multipart.NewWriter(buf)
 | 
				
			||||||
 | 
						w, err := mw.CreateFormFile("file", "test")
 | 
				
			||||||
 | 
						if assert.NoError(t, err) {
 | 
				
			||||||
 | 
							w.Write([]byte("test"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mw.Close()
 | 
				
			||||||
 | 
						c, _ := CreateTestContext(httptest.NewRecorder())
 | 
				
			||||||
 | 
						c.Request, _ = http.NewRequest("POST", "/", buf)
 | 
				
			||||||
 | 
						c.Request.Header.Set("Content-Type", mw.FormDataContentType())
 | 
				
			||||||
 | 
						f, err := c.FormFile("file")
 | 
				
			||||||
 | 
						if assert.NoError(t, err) {
 | 
				
			||||||
 | 
							assert.Equal(t, "test", f.Filename)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestContextMultipartForm(t *testing.T) {
 | 
				
			||||||
 | 
						buf := new(bytes.Buffer)
 | 
				
			||||||
 | 
						mw := multipart.NewWriter(buf)
 | 
				
			||||||
 | 
						mw.WriteField("foo", "bar")
 | 
				
			||||||
 | 
						mw.Close()
 | 
				
			||||||
 | 
						c, _ := CreateTestContext(httptest.NewRecorder())
 | 
				
			||||||
 | 
						c.Request, _ = http.NewRequest("POST", "/", buf)
 | 
				
			||||||
 | 
						c.Request.Header.Set("Content-Type", mw.FormDataContentType())
 | 
				
			||||||
 | 
						f, err := c.MultipartForm()
 | 
				
			||||||
 | 
						if assert.NoError(t, err) {
 | 
				
			||||||
 | 
							assert.NotNil(t, f)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestContextReset(t *testing.T) {
 | 
					func TestContextReset(t *testing.T) {
 | 
				
			||||||
	router := New()
 | 
						router := New()
 | 
				
			||||||
	c := router.allocateContext()
 | 
						c := router.allocateContext()
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user