Allow streaming of multipart requests in Zuul proxy
It turns out that the suckiness of Zuul with multipart requests comes almost entirely from the Multipart handling in Spring's DispatcherServlet. This change makes the proxy routes available on an alternative path /zuul/<normal_path> (where /zuul is the default value of zuul.servletPath). I have tested those with 800MB file uploads using the main method in the FormZuulServletProxyApplicationTests and the main observation is that there is no OutOfMemory error (no-one tries to download the complete request body). It works with Ribbon and with the simple (HttpClient) filter. With Ribbon you will need to set some timeouts if you want to upload files as large as that, e.g. see application.yml in the tests: hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000 ribbon: ConnectTimeout: 3000 ReadTimeout: 60000 You need to set "Transfer-Encoding: chunked" in the incoming request. Chrome does not do this by default apparently, but I was able to test with curl, e.g. $ curl -v -H "Transfer-Encoding: chunked" \ -F "file=@mylarg.iso" \ localhost:9999/zuul/direct/file The old proxy paths through the DispatcherServlet are still available (for backwards compatibility and for convenience of having the paths available at the root of the context path). Fixes gh-254
This commit is contained in:
@@ -860,6 +860,37 @@ An application with the `@EnableZuulProxy` could act as a standalone
|
||||
server if you set a default route ("/"), for example `zuul.route.home:
|
||||
/` would route all traffic (i.e. "/**") to the "home" service.
|
||||
|
||||
=== Uploading Files through Zuul
|
||||
|
||||
If you `@EnableZuulProxy` you can use the proxy paths to
|
||||
upload files and it should just work as long as the files
|
||||
are small. For large files there is an alternative path
|
||||
which bypasses the Spring `DispatcherServlet` (to
|
||||
avoid multipart processing) in "/zuul/*". I.e. if
|
||||
`zuul.routes.customers=/customers/**` then you can
|
||||
POST large files to "/zuul/customers/*". The servlet
|
||||
path is externalized via `zuul.servletPath`. Extremely
|
||||
large files will also require elevated timeout settings
|
||||
if the proxy route takes you through a Ribbon load
|
||||
balancer, e.g.
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
|
||||
ribbon:
|
||||
ConnectTimeout: 3000
|
||||
ReadTimeout: 60000
|
||||
----
|
||||
|
||||
Note that for streaming to work with large files, you need to use chunked encoding in the request (which some browsers
|
||||
do not do by default). E.g. on the command line:
|
||||
|
||||
----
|
||||
$ curl -v -H "Transfer-Encoding: chunked" \
|
||||
-F "file=@mylarge.iso" localhost:9999/zuul/simple/file
|
||||
----
|
||||
|
||||
=== Plain Embedded Zuul
|
||||
|
||||
You can also run a Zuul server without the proxying, or switch on parts of the proxying platform selectively, if you
|
||||
|
||||
Reference in New Issue
Block a user