mirror of
https://github.com/kataras/iris.git
synced 2025-03-13 21:36:28 +01:00
Update the _examples/http_request/upload-file to fill the gap, relative discussion: https://github.com/kataras/iris/issues/979
Former-commit-id: a113e8815a6a2821a80ac424f52302528a6e71b5
This commit is contained in:
parent
3c6d1f2fa3
commit
4eeffd07c7
|
@ -11,6 +11,8 @@ import (
|
|||
"github.com/kataras/iris"
|
||||
)
|
||||
|
||||
const maxSize = 5 << 20 // 5MB
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
|
@ -32,18 +34,72 @@ func main() {
|
|||
ctx.View("upload_form.html", token)
|
||||
})
|
||||
|
||||
// Handle the post request from the upload_form.html to the server
|
||||
app.Post("/upload", func(ctx iris.Context) {
|
||||
// iris.LimitRequestBodySize(32 <<20) as middleware to a route
|
||||
// or use ctx.SetMaxRequestBodySize(32 << 20)
|
||||
// to limit the whole request body size,
|
||||
//
|
||||
// or let the configuration option at app.Run for global setting
|
||||
// for POST/PUT methods, including uploads of course.
|
||||
/* Read before continue.
|
||||
|
||||
0. The default post max size is 32MB,
|
||||
you can extend it to read more data using the `iris.WithPostMaxMemory(maxSize)` configurator at `app.Run`,
|
||||
note that this will not be enough for your needs, read below.
|
||||
|
||||
1. The faster way to check the size is using the `ctx.GetContentLength()` which returns the whole request's size
|
||||
(plus a logical number like 2MB or even 10MB for the rest of the size like headers). You can create a
|
||||
middleware to adapt this to any necessary handler.
|
||||
|
||||
myLimiter := func(ctx iris.Context) {
|
||||
if ctx.GetContentLength() > maxSize { // + 2 << 20 {
|
||||
ctx.StatusCode(iris.StatusRequestEntityTooLarge)
|
||||
return
|
||||
}
|
||||
ctx.Next()
|
||||
}
|
||||
|
||||
app.Post("/upload", myLimiter, myUploadHandler)
|
||||
|
||||
Most clients will set the "Content-Length" header (like browsers) but it's always better to make sure that any client
|
||||
can't send data that your server can't or doesn't want to handle. This can be happen using
|
||||
the `app.Use(LimitRequestBodySize(maxSize))` (as app or route middleware)
|
||||
or the `ctx.SetMaxRequestBodySize(maxSize)` to limit the request based on a customized logic inside a particular handler, they're the same,
|
||||
read below.
|
||||
|
||||
2. You can force-limit the request body size inside a handler using the `ctx.SetMaxRequestBodySize(maxSize)`,
|
||||
this will force the connection to close if the incoming data are larger (most clients will receive it as "connection reset"),
|
||||
use that to make sure that the client will not send data that your server can't or doesn't want to accept, as a fallback.
|
||||
|
||||
app.Post("/upload", iris.LimitRequestBodySize(maxSize), myUploadHandler)
|
||||
|
||||
OR
|
||||
|
||||
app.Post("/upload", func(ctx iris.Context){
|
||||
ctx.SetMaxRequestBodySize(maxSize)
|
||||
|
||||
// [...]
|
||||
})
|
||||
|
||||
3. Another way is to receive the data and check the second return value's `Size` value of the `ctx.FormFile`, i.e `info.Size`, this will give you
|
||||
the exact file size, not the whole incoming request data length.
|
||||
|
||||
app.Post("/", func(ctx iris.Context){
|
||||
file, info, err := ctx.FormFile("uploadfile")
|
||||
if err != nil {
|
||||
ctx.StatusCode(iris.StatusInternalServerError)
|
||||
ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>")
|
||||
return
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
if info.Size > maxSize {
|
||||
ctx.StatusCode(iris.StatusRequestEntityTooLarge)
|
||||
return
|
||||
}
|
||||
|
||||
// [...]
|
||||
})
|
||||
*/
|
||||
|
||||
// Handle the post request from the upload_form.html to the server
|
||||
app.Post("/upload", iris.LimitRequestBodySize(maxSize+1<<20), func(ctx iris.Context) {
|
||||
// Get the file from the request.
|
||||
file, info, err := ctx.FormFile("uploadfile")
|
||||
|
||||
if err != nil {
|
||||
ctx.StatusCode(iris.StatusInternalServerError)
|
||||
ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>")
|
||||
|
@ -68,6 +124,6 @@ func main() {
|
|||
io.Copy(out, file)
|
||||
})
|
||||
|
||||
// start the server at http://localhost:8080 with post limit at 32 MB.
|
||||
app.Run(iris.Addr(":8080"), iris.WithPostMaxMemory(32<<20))
|
||||
// start the server at http://localhost:8080 with post limit at 5 MB.
|
||||
app.Run(iris.Addr(":8080") /* 0.*/, iris.WithPostMaxMemory(maxSize))
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Upload file</title>
|
||||
<title>Upload file</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form enctype="multipart/form-data"
|
||||
action="http://127.0.0.1:8080/upload" method="POST">
|
||||
<input type="file" name="uploadfile" /> <input type="hidden"
|
||||
name="token" value="{{.}}" /> <input type="submit" value="upload" />
|
||||
<form enctype="multipart/form-data" action="http://127.0.0.1:8080/upload" method="POST">
|
||||
<input type="file" name="uploadfile" />
|
||||
<input type="hidden" name="token" value="{{.}}" />
|
||||
<input type="submit" value="upload" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
|
@ -432,6 +432,10 @@ type Context interface {
|
|||
// which may, setted before with the 'ContentType'.
|
||||
GetContentType() string
|
||||
|
||||
// GetContentLength returns the request's header value of "Content-Length".
|
||||
// Returns 0 if header was unable to be found or its value was not a valid number.
|
||||
GetContentLength() int64
|
||||
|
||||
// StatusCode sets the status code header to the response.
|
||||
// Look .GetStatusCode too.
|
||||
StatusCode(statusCode int)
|
||||
|
@ -1597,6 +1601,16 @@ func (ctx *context) GetContentType() string {
|
|||
return ctx.writer.Header().Get(ContentTypeHeaderKey)
|
||||
}
|
||||
|
||||
// GetContentLength returns the request's header value of "Content-Length".
|
||||
// Returns 0 if header was unable to be found or its value was not a valid number.
|
||||
func (ctx *context) GetContentLength() int64 {
|
||||
if v := ctx.GetHeader(ContentLengthHeaderKey); v != "" {
|
||||
n, _ := strconv.ParseInt(v, 10, 64)
|
||||
return n
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// StatusCode sets the status code header to the response.
|
||||
// Look .GetStatusCode & .FireStatusCode too.
|
||||
//
|
||||
|
@ -1966,7 +1980,10 @@ func (ctx *context) FormFile(key string) (multipart.File, *multipart.FileHeader,
|
|||
// here but do it in order to apply the post limit,
|
||||
// the internal request.FormFile will not do it if that's filled
|
||||
// and it's not a stream body.
|
||||
ctx.request.ParseMultipartForm(ctx.Application().ConfigurationReadOnly().GetPostMaxMemory())
|
||||
if err := ctx.request.ParseMultipartForm(ctx.Application().ConfigurationReadOnly().GetPostMaxMemory()); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return ctx.request.FormFile(key)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user