From afae2da5a6c3b7cb4c01b62cc80ca03dbda11949 Mon Sep 17 00:00:00 2001 From: Shuai Lin Date: Thu, 24 Nov 2016 09:40:53 +0800 Subject: [PATCH] Handle the case where content-length header is missing in the response Fix #592 How to reproduce the "missing content-length" case: - Upload a relative big file to seafile server (larger than 300K is enough) - Add 'gzip_types *' in nginx config In such a setup, nginx would be forced to use chunked transfer-encoding because when gzipped is enabled it can't know the exact response size at the moment it sends the response header. --- .../com/seafile/seadroid2/SeafConnection.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/seafile/seadroid2/SeafConnection.java b/app/src/main/java/com/seafile/seadroid2/SeafConnection.java index 1d0488a22..95c0e2983 100644 --- a/app/src/main/java/com/seafile/seadroid2/SeafConnection.java +++ b/app/src/main/java/com/seafile/seadroid2/SeafConnection.java @@ -335,7 +335,7 @@ public String getAvatar(String email, int size) throws SeafException { String apiPath = String.format("api2/avatars/user/%s/resized/%d", email, size); HttpRequest req = prepareApiGetRequest(apiPath); checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK); - + String result = new String(req.bytes(), "UTF-8"); return result; } catch (SeafException e) { @@ -556,16 +556,27 @@ private File getFileFromLink(String dlink, String path, String localPath, checkRequestResponseStatus(req, HttpURLConnection.HTTP_OK); if (monitor != null) { - Long size; + Long size = -1L; if (req.contentLength() > 0) { - size = Long.valueOf(req.contentLength()); + size = Long.valueOf(req.contentLength()); } else { - /*if (req.header(HttpRequest.HEADER_CONTENT_LENGTH) == null) { - throw SeafException.illFormatException; - }*/ - size = Long.parseLong(req.header(HttpRequest.HEADER_CONTENT_LENGTH)); + // The req.contentLength() returns an int, which has a max value of + // 2GB. So if a file size exceeds 2GB, request.contentLength() would + // return -1. In such case, we parse the content length from the raw + // header string directly. + // + // See https://github.com/kevinsawicki/http-request/blob/http-request-5.6/lib/src/main/java/com/github/kevinsawicki/http/HttpRequest.java#L2519-L2521 + String contentLengthheader = req.header(HttpRequest.HEADER_CONTENT_LENGTH); + // The server may not send us the "Content-Length" header in the + // response, e.g. when the server is using chunked transfer encoding. + if (contentLengthheader != null) { + size = Long.parseLong(contentLengthheader); + } + } + + if (size > 0) { + monitor.onProgressNotify(size, false); } - monitor.onProgressNotify(size, false); } File tmp = DataManager.createTempFile();