mirror of
https://github.com/kataras/iris.git
synced 2025-03-15 05:26:26 +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"
|
"github.com/kataras/iris"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const maxSize = 5 << 20 // 5MB
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
|
|
||||||
|
@ -32,18 +34,72 @@ func main() {
|
||||||
ctx.View("upload_form.html", token)
|
ctx.View("upload_form.html", token)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Handle the post request from the upload_form.html to the server
|
/* Read before continue.
|
||||||
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.
|
|
||||||
|
|
||||||
|
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.
|
// Get the file from the request.
|
||||||
file, info, err := ctx.FormFile("uploadfile")
|
file, info, err := ctx.FormFile("uploadfile")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.StatusCode(iris.StatusInternalServerError)
|
ctx.StatusCode(iris.StatusInternalServerError)
|
||||||
ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>")
|
ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>")
|
||||||
|
@ -68,6 +124,6 @@ func main() {
|
||||||
io.Copy(out, file)
|
io.Copy(out, file)
|
||||||
})
|
})
|
||||||
|
|
||||||
// start the server at http://localhost:8080 with post limit at 32 MB.
|
// start the server at http://localhost:8080 with post limit at 5 MB.
|
||||||
app.Run(iris.Addr(":8080"), iris.WithPostMaxMemory(32<<20))
|
app.Run(iris.Addr(":8080") /* 0.*/, iris.WithPostMaxMemory(maxSize))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Upload file</title>
|
<title>Upload file</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<form enctype="multipart/form-data"
|
<form enctype="multipart/form-data" action="http://127.0.0.1:8080/upload" method="POST">
|
||||||
action="http://127.0.0.1:8080/upload" method="POST">
|
<input type="file" name="uploadfile" />
|
||||||
<input type="file" name="uploadfile" /> <input type="hidden"
|
<input type="hidden" name="token" value="{{.}}" />
|
||||||
name="token" value="{{.}}" /> <input type="submit" value="upload" />
|
<input type="submit" value="upload" />
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -432,6 +432,10 @@ type Context interface {
|
||||||
// which may, setted before with the 'ContentType'.
|
// which may, setted before with the 'ContentType'.
|
||||||
GetContentType() string
|
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.
|
// StatusCode sets the status code header to the response.
|
||||||
// Look .GetStatusCode too.
|
// Look .GetStatusCode too.
|
||||||
StatusCode(statusCode int)
|
StatusCode(statusCode int)
|
||||||
|
@ -1597,6 +1601,16 @@ func (ctx *context) GetContentType() string {
|
||||||
return ctx.writer.Header().Get(ContentTypeHeaderKey)
|
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.
|
// StatusCode sets the status code header to the response.
|
||||||
// Look .GetStatusCode & .FireStatusCode too.
|
// 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,
|
// here but do it in order to apply the post limit,
|
||||||
// the internal request.FormFile will not do it if that's filled
|
// the internal request.FormFile will not do it if that's filled
|
||||||
// and it's not a stream body.
|
// 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)
|
return ctx.request.FormFile(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user