From 6596aa3b715b3bc0f12f8c319e4bad23012c9e11 Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Tue, 3 Jan 2017 10:34:27 +0800 Subject: [PATCH 1/3] [ci skip] update readme for upload file. Signed-off-by: Bo-Yi Wu --- README.md | 60 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 19d9088..7669edf 100644 --- a/README.md +++ b/README.md @@ -229,34 +229,64 @@ func main() { id: 1234; page: 1; name: manu; message: this_is_great ``` -### Another example: upload file +### upload file -References issue [#548](https://github.com/gin-gonic/gin/issues/548). +#### upload single file + +References issue [#774](https://github.com/gin-gonic/gin/issues/774). ```go func main() { router := gin.Default() - router.POST("/upload", func(c *gin.Context) { + // single file + file, _ := c.FormFile("file") + log.Println(file.Filename) - file, header , err := c.Request.FormFile("upload") - filename := header.Filename - fmt.Println(header.Filename) - out, err := os.Create("./tmp/"+filename+".png") - if err != nil { - log.Fatal(err) - } - defer out.Close() - _, err = io.Copy(out, file) - if err != nil { - log.Fatal(err) - } + c.String(http.StatusOK, "Uploaded...") }) router.Run(":8080") } ``` +curl command: + +```bash +curl -X POST http://localhost:8080/upload \ + -F "file=@/Users/appleboy/test.zip" \ + -H "Content-Type: multipart/form-data" +``` + +#### upload multiple files + +```go +func main() { + router := gin.Default() + router.POST("/upload", func(c *gin.Context) { + // Multipart form + form, _ := c.MultipartForm() + files := form.File["upload[]"] + + for _, file := range files { + log.Println(file.Filename) + } + c.String(http.StatusOK, "Uploaded...") + }) + router.Run(":8080") +} +``` + +curl command: + +```bash +curl -X POST http://localhost:8080/upload \ + -F "upload[]=@/Users/appleboy/test1.zip" \ + -F "upload[]=@/Users/appleboy/test2.zip" \ + -H "Content-Type: multipart/form-data" +``` + #### Grouping routes + ```go func main() { router := gin.Default() From 17af53a565bff4483c734fe00f1870a4ecf05afc Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Tue, 3 Jan 2017 11:50:35 +0800 Subject: [PATCH 2/3] add upload file example. Signed-off-by: Bo-Yi Wu --- README.md | 4 +- examples/upload-file/multiple/main.go | 39 +++++++++++++++++++ .../upload-file/multiple/public/index.html | 17 ++++++++ examples/upload-file/single/main.go | 34 ++++++++++++++++ examples/upload-file/single/public/index.html | 16 ++++++++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 examples/upload-file/multiple/main.go create mode 100644 examples/upload-file/multiple/public/index.html create mode 100644 examples/upload-file/single/main.go create mode 100644 examples/upload-file/single/public/index.html diff --git a/README.md b/README.md index 7669edf..571c7ce 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,7 @@ id: 1234; page: 1; name: manu; message: this_is_great #### upload single file -References issue [#774](https://github.com/gin-gonic/gin/issues/774). +References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](examples/upload-file/single). ```go func main() { @@ -259,6 +259,8 @@ curl -X POST http://localhost:8080/upload \ #### upload multiple files +See the detail [example code](examples/upload-file/multiple). + ```go func main() { router := gin.Default() diff --git a/examples/upload-file/multiple/main.go b/examples/upload-file/multiple/main.go new file mode 100644 index 0000000..2f4e9b5 --- /dev/null +++ b/examples/upload-file/multiple/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + "io" + "net/http" + "os" + + "github.com/gin-gonic/gin" +) + +func main() { + router := gin.Default() + router.Static("/", "./public") + router.POST("/upload", func(c *gin.Context) { + name := c.PostForm("name") + email := c.PostForm("email") + + // Multipart form + form, _ := c.MultipartForm() + files := form.File["files"] + + for _, file := range files { + // Source + src, _ := file.Open() + defer src.Close() + + // Destination + dst, _ := os.Create(file.Filename) + defer dst.Close() + + // Copy + io.Copy(dst, src) + } + + c.String(http.StatusOK, fmt.Sprintf("Uploaded successfully %d files with fields name=%s and email=%s.", len(files), name, email)) + }) + router.Run(":8080") +} diff --git a/examples/upload-file/multiple/public/index.html b/examples/upload-file/multiple/public/index.html new file mode 100644 index 0000000..b846360 --- /dev/null +++ b/examples/upload-file/multiple/public/index.html @@ -0,0 +1,17 @@ + + + + + Multiple file upload + + +

Upload multiple files with fields

+ +
+ Name:
+ Email:
+ Files:

+ +
+ + diff --git a/examples/upload-file/single/main.go b/examples/upload-file/single/main.go new file mode 100644 index 0000000..9acf500 --- /dev/null +++ b/examples/upload-file/single/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "fmt" + "io" + "net/http" + "os" + + "github.com/gin-gonic/gin" +) + +func main() { + router := gin.Default() + router.Static("/", "./public") + router.POST("/upload", func(c *gin.Context) { + name := c.PostForm("name") + email := c.PostForm("email") + + // Source + file, _ := c.FormFile("file") + src, _ := file.Open() + defer src.Close() + + // Destination + dst, _ := os.Create(file.Filename) + defer dst.Close() + + // Copy + io.Copy(dst, src) + + c.String(http.StatusOK, fmt.Sprintf("File %s uploaded successfully with fields name=%s and email=%s.", file.Filename, name, email)) + }) + router.Run(":8080") +} diff --git a/examples/upload-file/single/public/index.html b/examples/upload-file/single/public/index.html new file mode 100644 index 0000000..b0c2a80 --- /dev/null +++ b/examples/upload-file/single/public/index.html @@ -0,0 +1,16 @@ + + + + + Single file upload + + +

Upload single file with fields

+ +
+ Name:
+ Email:
+ Files:

+ +
+ From 050937dab80745a7fc666e5aa0b61f76169c48dc Mon Sep 17 00:00:00 2001 From: Javier Provecho Fernandez Date: Tue, 3 Jan 2017 17:04:29 +0100 Subject: [PATCH 3/3] Improve "Upload file" example, Fix MD typos --- README.md | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 571c7ce..0c08556 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ BenchmarkZeus_GithubAll | 2000 | 944234 | 300688 | 2648 ## API Examples -#### Using GET, POST, PUT, PATCH, DELETE and OPTIONS +### Using GET, POST, PUT, PATCH, DELETE and OPTIONS ```go func main() { @@ -137,7 +137,7 @@ func main() { } ``` -#### Parameters in path +### Parameters in path ```go func main() { @@ -162,7 +162,7 @@ func main() { } ``` -#### Querystring parameters +### Querystring parameters ```go func main() { router := gin.Default() @@ -229,9 +229,9 @@ func main() { id: 1234; page: 1; name: manu; message: this_is_great ``` -### upload file +### Upload files -#### upload single file +#### Single file References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](examples/upload-file/single). @@ -243,13 +243,13 @@ func main() { file, _ := c.FormFile("file") log.Println(file.Filename) - c.String(http.StatusOK, "Uploaded...") + c.String(http.StatusOK, fmt.Printf("'%s' uploaded!", file.Filename)) }) router.Run(":8080") } ``` -curl command: +How to `curl`: ```bash curl -X POST http://localhost:8080/upload \ @@ -257,7 +257,7 @@ curl -X POST http://localhost:8080/upload \ -H "Content-Type: multipart/form-data" ``` -#### upload multiple files +#### Multiple files See the detail [example code](examples/upload-file/multiple). @@ -272,13 +272,13 @@ func main() { for _, file := range files { log.Println(file.Filename) } - c.String(http.StatusOK, "Uploaded...") + c.String(http.StatusOK, fmt.Printf("%d files uploaded!", len(files))) }) router.Run(":8080") } ``` -curl command: +How to `curl`: ```bash curl -X POST http://localhost:8080/upload \ @@ -287,7 +287,7 @@ curl -X POST http://localhost:8080/upload \ -H "Content-Type: multipart/form-data" ``` -#### Grouping routes +### Grouping routes ```go func main() { @@ -314,7 +314,7 @@ func main() { ``` -#### Blank Gin without middleware by default +### Blank Gin without middleware by default Use @@ -328,7 +328,7 @@ r := gin.Default() ``` -#### Using middleware +### Using middleware ```go func main() { // Creates a router without any middleware by default @@ -363,7 +363,7 @@ func main() { } ``` -#### Model binding and validation +### Model binding and validation To bind a request body into a type, use model binding. We currently support binding of JSON, XML and standard form values (foo=bar&boo=baz). @@ -413,7 +413,7 @@ func main() { } ``` -#### Bind Query String +### Bind Query String See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292). @@ -489,7 +489,7 @@ $ curl -v --form user=user --form password=password http://localhost:8080/login ``` -#### XML, JSON and YAML rendering +### XML, JSON and YAML rendering ```go func main() { @@ -528,7 +528,7 @@ func main() { } ``` -####Serving static files +### Serving static files ```go func main() { @@ -542,7 +542,7 @@ func main() { } ``` -####HTML rendering +### HTML rendering Using LoadHTMLGlob() or LoadHTMLFiles() @@ -622,7 +622,7 @@ func main() { ``` -#### Redirects +### Redirects Issuing a HTTP redirect is easy: @@ -634,7 +634,7 @@ r.GET("/test", func(c *gin.Context) { Both internal and external locations are supported. -#### Custom Middleware +### Custom Middleware ```go func Logger() gin.HandlerFunc { @@ -674,7 +674,7 @@ func main() { } ``` -#### Using BasicAuth() middleware +### Using BasicAuth() middleware ```go // simulate some private data var secrets = gin.H{ @@ -713,7 +713,7 @@ func main() { ``` -#### Goroutines inside a middleware +### Goroutines inside a middleware When starting inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy. ```go @@ -745,7 +745,7 @@ func main() { } ``` -#### Custom HTTP configuration +### Custom HTTP configuration Use `http.ListenAndServe()` directly, like this: @@ -772,7 +772,7 @@ func main() { } ``` -#### Graceful restart or stop +### Graceful restart or stop Do you want to graceful restart or stop your web server? There are some ways this can be done. @@ -803,7 +803,7 @@ An alternative to endless: - You should add/modify tests to cover your proposed code changes. - If your pull request contains a new feature, please document it on the README. -## Example +## Users Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework.