{"action":"created","issue":{"url":"https://api.github.com/repos/square/okhttp/issues/1517","labels_url":"https://api.github.com/repos/square/okhttp/issues/1517/labels{/name}","comments_url":"https://api.github.com/repos/square/okhttp/issues/1517/comments","events_url":"https://api.github.com/repos/square/okhttp/issues/1517/events","html_url":"https://github.com/square/okhttp/issues/1517","id":63091090,"number":1517,"title":"EOFException in RealBufferedSource.readUtf8LineStrict(): 0-bytes in stream","user":{"login":"swankjesse","id":133019,"avatar_url":"https://avatars.githubusercontent.com/u/133019?v=3","gravatar_id":"","url":"https://api.github.com/users/swankjesse","html_url":"https://github.com/swankjesse","followers_url":"https://api.github.com/users/swankjesse/followers","following_url":"https://api.github.com/users/swankjesse/following{/other_user}","gists_url":"https://api.github.com/users/swankjesse/gists{/gist_id}","starred_url":"https://api.github.com/users/swankjesse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swankjesse/subscriptions","organizations_url":"https://api.github.com/users/swankjesse/orgs","repos_url":"https://api.github.com/users/swankjesse/repos","events_url":"https://api.github.com/users/swankjesse/events{/privacy}","received_events_url":"https://api.github.com/users/swankjesse/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/square/okhttp/labels/bug","name":"bug","color":"fc2929"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/square/okhttp/milestones/6","html_url":"https://github.com/square/okhttp/milestones/Icebox","labels_url":"https://api.github.com/repos/square/okhttp/milestones/6/labels","id":606107,"number":6,"title":"Icebox","description":null,"creator":{"login":"swankjesse","id":133019,"avatar_url":"https://avatars.githubusercontent.com/u/133019?v=3","gravatar_id":"","url":"https://api.github.com/users/swankjesse","html_url":"https://github.com/swankjesse","followers_url":"https://api.github.com/users/swankjesse/followers","following_url":"https://api.github.com/users/swankjesse/following{/other_user}","gists_url":"https://api.github.com/users/swankjesse/gists{/gist_id}","starred_url":"https://api.github.com/users/swankjesse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swankjesse/subscriptions","organizations_url":"https://api.github.com/users/swankjesse/orgs","repos_url":"https://api.github.com/users/swankjesse/repos","events_url":"https://api.github.com/users/swankjesse/events{/privacy}","received_events_url":"https://api.github.com/users/swankjesse/received_events","type":"User","site_admin":false},"open_issues":43,"closed_issues":11,"state":"open","created_at":"2014-03-22T02:57:09Z","updated_at":"2016-01-16T04:20:00Z","due_on":null,"closed_at":null},"comments":27,"created_at":"2015-03-19T21:08:32Z","updated_at":"2016-01-17T09:56:47Z","closed_at":null,"body":"We're getting an EOF exception with size=0 in the stream.\r\n\r\n```\r\njava.io.EOFException: \\n not found: size=0 content=...\r\n            at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:200)\r\n            at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:187)\r\n            at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)\r\n            at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:791)\r\n            at com.squareup.okhttp.internal.http.HttpEngine.access$200(HttpEngine.java:90)\r\n```\r\n\r\n(Forked from [issue 1114](https://github.com/square/okhttp/issues/1114).)"},"comment":{"url":"https://api.github.com/repos/square/okhttp/issues/comments/172306839","html_url":"https://github.com/square/okhttp/issues/1517#issuecomment-172306839","issue_url":"https://api.github.com/repos/square/okhttp/issues/1517","id":172306839,"user":{"login":"ImGauravC","id":683281,"avatar_url":"https://avatars.githubusercontent.com/u/683281?v=3","gravatar_id":"","url":"https://api.github.com/users/ImGauravC","html_url":"https://github.com/ImGauravC","followers_url":"https://api.github.com/users/ImGauravC/followers","following_url":"https://api.github.com/users/ImGauravC/following{/other_user}","gists_url":"https://api.github.com/users/ImGauravC/gists{/gist_id}","starred_url":"https://api.github.com/users/ImGauravC/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ImGauravC/subscriptions","organizations_url":"https://api.github.com/users/ImGauravC/orgs","repos_url":"https://api.github.com/users/ImGauravC/repos","events_url":"https://api.github.com/users/ImGauravC/events{/privacy}","received_events_url":"https://api.github.com/users/ImGauravC/received_events","type":"User","site_admin":false},"created_at":"2016-01-17T09:56:47Z","updated_at":"2016-01-17T09:56:47Z","body":"I can post the code we use for uploads. \r\nS3Data object is populated using our server api and contains information about the S3 key, acl etc.\r\n \r\n````\r\npublic class OkHttpUploader  {\r\n    private static final String TAG = \"OkHttpUploader\";\r\n\r\n    protected String mBucketUrl;\r\n    protected S3Data mData;\r\n    protected ResponseCallback mCallback;\r\n    public OkHttpUploader(String bucketUrl, S3Data data, ResponseCallback cb) {\r\n        mBucketUrl = bucketUrl;\r\n        mData = data;\r\n        mCallback = cb;\r\n    }\r\n\r\n    @Override\r\n    public void upload(final byte[] imageData) {\r\n        RequestBody requestBody = getS3RequestBody(mData)\r\n                .addFormDataPart(\"file\", \"upload.jpg\", RequestBody.create(MediaType.parse(\"image/jpeg\"), imageData))\r\n                .build();\r\n        makeMultipartS3Request(requestBody);\r\n    }\r\n\r\n    @Override\r\n    public void upload(final File file) {\r\n        RequestBody requestBody = getS3RequestBody(mData)\r\n                .addFormDataPart(\"file\", \"upload.jpg\", RequestBody.create(MediaType.parse(\"image/jpeg\"), file))\r\n                .build();\r\n        makeMultipartS3Request(requestBody);\r\n    }\r\n\r\n    private MultipartBuilder getS3RequestBody(final S3Data data) {\r\n        return new MultipartBuilder()\r\n                .addFormDataPart(\"key\", data.getKey())\r\n                .addFormDataPart(\"AWSAccessKeyId\", data.getAWSAccessKeyId())\r\n                .addFormDataPart(\"acl\", data.getAcl())\r\n                .addFormDataPart(\"policy\", data.getPolicy())\r\n                .addFormDataPart(\"signature\", data.getSignature())\r\n                .addFormDataPart(\"Content-Type\", \"image/jpeg\")\r\n                .addFormDataPart(\"success_action_status\", data.getSuccessActionStatus());\r\n    }\r\n\r\n    private void makeMultipartS3Request(final RequestBody requestBody) {\r\n        makeMultipartS3RequestHelper(requestBody, 0);\r\n    }\r\n\r\n    private void makeMultipartS3RequestHelper(final RequestBody requestBody, final int currentAttempt) {\r\n        final Request request = new Request.Builder()\r\n                .url(mBucketUrl)\r\n                .post(requestBody)\r\n                .build();\r\n\r\n        Looper threadLooper = Looper.myLooper(); // looper of the calling thread\r\n        final Handler threadHandler = threadLooper != null ? new Handler(threadLooper) : null;\r\n        OkHttpClient client = new OkHttpClient();\r\n        client.setRetryOnConnectionFailure(true);\r\n        client.newCall(request).enqueue(new Callback() {\r\n            @Override\r\n            public void onFailure(Request request, IOException e) {\r\n                Log.d(TAG, \"Failure doing multipart request\" + request.urlString());\r\n                if (currentAttempt >= 1) {\r\n                    parseS3FailureResponse(request, threadHandler);\r\n                } else {\r\n                    Log.d(TAG, \"retrying s3 upload \" +  mBucketUrl);\r\n                    makeMultipartS3RequestHelper(requestBody, currentAttempt + 1);\r\n                }\r\n            }\r\n\r\n            @Override\r\n            public void onResponse(Response response) throws IOException {\r\n                parseS3Response(response, threadHandler);\r\n            }\r\n        });\r\n    }\r\n\r\n    private void parseS3FailureResponse(final Request request, Handler threadHandler) {\r\n        if (threadHandler != null) {\r\n            threadHandler.post(new Runnable() {\r\n                @Override\r\n                public void run() {\r\n                    mCallback.onFailure(\"Network Error:  headers: \" + request.headers().toString());\r\n                }\r\n            });\r\n        } else {\r\n            mCallback.onFailure(\"Network Error\");\r\n        }\r\n    }\r\n\r\n    private void parseS3Response(Response response, Handler threadHandler) {\r\n        try {\r\n            if (response.isSuccessful()) {\r\n                onResponseSuccess(response, threadHandler);\r\n            } else {\r\n                onResponseError(response, threadHandler);\r\n            }\r\n        } catch (JSONException e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n    private void onResponseSuccess(Response response, Handler threadHandler) throws JSONException {\r\n        Headers responseHeaders = response.headers();\r\n        for (int i = 0; i < responseHeaders.size(); i++) {\r\n            if (\"Location\".equals(responseHeaders.name(i))) {\r\n                String uploadedUrl = responseHeaders.value(i);\r\n                try {\r\n                    uploadedUrl = URLDecoder.decode(uploadedUrl, \"utf-8\");\r\n                } catch (UnsupportedEncodingException e) {\r\n                    Log.d(TAG, \"unsupported encoding exception\");\r\n                }\r\n                Log.d(TAG, \"Uploaded: url=\" + uploadedUrl);\r\n                final JSONObject responseJson = new JSONObject();\r\n                responseJson.put(\"url\", uploadedUrl);\r\n                if (threadHandler != null) {\r\n                    threadHandler.post(new Runnable() {\r\n                        @Override\r\n                        public void run() {\r\n                            try {\r\n                                mCallback.onSuccess(responseJson);\r\n                            } catch (JSONException e) {\r\n                                Log.d(TAG, \"exce\");\r\n                            }\r\n                        }\r\n                    });\r\n                } else {\r\n                    mCallback.onSuccess(responseJson);\r\n                }\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    private void onResponseError(Response response, Handler threadHandler) throws JSONException {\r\n        if (threadHandler != null) {\r\n            threadHandler.post(new Runnable() {\r\n                @Override\r\n                public void run() {\r\n                    mCallback.onError(\"Upload Failed!\");\r\n                }\r\n            });\r\n        } else {\r\n            mCallback.onError(\"Upload Failed!\");\r\n        }\r\n    }\r\n}\r\n````"}}