diff options
author | Fabian Lange <lange.fabian@gmail.com> | 2013-06-12 21:21:31 +0200 |
---|---|---|
committer | Fabian Lange <lange.fabian@gmail.com> | 2013-07-08 15:05:36 +0200 |
commit | 68be95e48405be0e5d54b3d8ddb66de454fcbfed (patch) | |
tree | 1e66059faac624bb100f8a836761e6c0fb708965 /server/src | |
parent | cd9bd20c52423e9970d1945c374e4cbefff82569 (diff) | |
download | vaadin-framework-68be95e48405be0e5d54b3d8ddb66de454fcbfed.tar.gz vaadin-framework-68be95e48405be0e5d54b3d8ddb66de454fcbfed.zip |
Support uploading files larger 2GB via drag and drop and file input (#11947).
Vaadin mostly just passes through the value from the Javascript File object
on drag and drop. As per specification (http://www.w3.org/TR/file-upload/#blob)
the size value can be "long". The size attribute of Html5File was already long,
but this patch makes sure long values actually are transported correctly from
the client side Transferable. Additionally, the file upload handling in
FileUploadHandler was determining the length of the upload via the Servlet Spec
getContentLength method of the request. However the spec was written at a time
where 2GB were unthinkable. Luckily containers return this value by querying
the Content-Length header, which can transport values of "long". So instead of
using the Servlet Spec method, FileUploadHandler evaluates the header itself.
AbstractStreamingEvent already was supporting "long" values. For Drag&Drop,
the file size needs to be serialized as double, because long is not supported
in JSNI.
Change-Id: I606fca7430c65c20144793fa011cb2f6ee3a0415
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/com/vaadin/server/communication/FileUploadHandler.java | 25 | ||||
-rw-r--r-- | server/src/com/vaadin/ui/DragAndDropWrapper.java | 2 |
2 files changed, 20 insertions, 7 deletions
diff --git a/server/src/com/vaadin/server/communication/FileUploadHandler.java b/server/src/com/vaadin/server/communication/FileUploadHandler.java index e9569d45a1..8014dba12d 100644 --- a/server/src/com/vaadin/server/communication/FileUploadHandler.java +++ b/server/src/com/vaadin/server/communication/FileUploadHandler.java @@ -271,7 +271,7 @@ public class FileUploadHandler implements RequestHandler { // if boundary string does not exist, the posted file is from // XHR2.post(File) doHandleXhrFilePost(session, request, response, streamVariable, - variableName, source, request.getContentLength()); + variableName, source, getContentLength(request)); } return true; } @@ -323,7 +323,7 @@ public class FileUploadHandler implements RequestHandler { final InputStream inputStream = request.getInputStream(); - int contentLength = request.getContentLength(); + long contentLength = getContentLength(request); boolean atStart = false; boolean firstFileFieldFound = false; @@ -390,9 +390,22 @@ public class FileUploadHandler implements RequestHandler { } + /* + * request.getContentLength() is limited to "int" by the Servlet + * specification. To support larger file uploads manually evaluate the + * Content-Length header which can contain long values. + */ + private long getContentLength(VaadinRequest request) { + try { + return Long.parseLong(request.getHeader("Content-Length")); + } catch (NumberFormatException e) { + return -1l; + } + } + private void handleFileUploadValidationAndData(VaadinSession session, InputStream inputStream, StreamVariable streamVariable, - String filename, String mimeType, int contentLength, + String filename, String mimeType, long contentLength, ClientConnector connector, String variableName) throws UploadException { session.lock(); @@ -461,7 +474,7 @@ public class FileUploadHandler implements RequestHandler { protected void doHandleXhrFilePost(VaadinSession session, VaadinRequest request, VaadinResponse response, StreamVariable streamVariable, String variableName, - ClientConnector owner, int contentLength) throws IOException { + ClientConnector owner, long contentLength) throws IOException { // These are unknown in filexhr ATM, maybe add to Accept header that // is accessible in portlets @@ -491,7 +504,7 @@ public class FileUploadHandler implements RequestHandler { */ protected final boolean streamToReceiver(VaadinSession session, final InputStream in, StreamVariable streamVariable, - String filename, String type, int contentLength) + String filename, String type, long contentLength) throws UploadException { if (streamVariable == null) { throw new IllegalStateException( @@ -499,7 +512,7 @@ public class FileUploadHandler implements RequestHandler { } OutputStream out = null; - int totalBytes = 0; + long totalBytes = 0; StreamingStartEventImpl startedEvent = new StreamingStartEventImpl( filename, type, contentLength); try { diff --git a/server/src/com/vaadin/ui/DragAndDropWrapper.java b/server/src/com/vaadin/ui/DragAndDropWrapper.java index 6c6aa3c3f4..7a2cfb82e4 100644 --- a/server/src/com/vaadin/ui/DragAndDropWrapper.java +++ b/server/src/com/vaadin/ui/DragAndDropWrapper.java @@ -54,7 +54,7 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, for (int i = 0; i < fc; i++) { Html5File file = new Html5File( (String) rawVariables.get("fn" + i), // name - (Integer) rawVariables.get("fs" + i), // size + ((Double) rawVariables.get("fs" + i)).longValue(), // size (String) rawVariables.get("ft" + i)); // mime String id = (String) rawVariables.get("fi" + i); files[i] = file; |