From c10d38bd2687ae013ca8ac12722947645b01b4c2 Mon Sep 17 00:00:00 2001 From: Andrea Lin Date: Tue, 29 Jan 2019 14:53:56 -0800 Subject: [PATCH 1/2] add Content-Length header always --- .../api/gax/httpjson/HttpRequestRunnable.java | 24 +++++++++++++++++++ .../httpjson/ApiMessageHttpRequestTest.java | 3 +++ 2 files changed, 27 insertions(+) diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java index 55e6d50e7..79d11103a 100644 --- a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java @@ -30,6 +30,7 @@ package com.google.api.gax.httpjson; import com.google.api.client.http.GenericUrl; +import com.google.api.client.http.HttpContent; import com.google.api.client.http.HttpMediaType; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpRequestFactory; @@ -51,6 +52,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import javax.annotation.Nullable; /** A runnable object that creates and executes an HTTP request. */ @AutoValue @@ -110,10 +112,32 @@ HttpRequest createHttpRequest() throws IOException { for (HttpJsonHeaderEnhancer enhancer : getHeaderEnhancers()) { enhancer.enhance(httpRequest.getHeaders()); } + + // Set Content-Length header to avoid 411s. + HttpJsonHeaderEnhancer contentLengthHeader = getContentLengthHeader(jsonHttpContent); + if (contentLengthHeader != null) { + contentLengthHeader.enhance(httpRequest.getHeaders()); + } + httpRequest.setParser(new JsonObjectParser(getJsonFactory())); return httpRequest; } + @Nullable + private HttpJsonHeaderEnhancer getContentLengthHeader(@Nullable HttpContent requestBody) { + long contentLength = 0; + try { + if (requestBody != null) { + contentLength = requestBody.getLength(); + } + } catch (IOException e) { + // Could not determine content length. + return null; + } + + return HttpJsonHeaderEnhancers.create("Content-Length", String.valueOf(contentLength)); + } + @Override public void run() { try { diff --git a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ApiMessageHttpRequestTest.java b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ApiMessageHttpRequestTest.java index 05e99fbe4..5477e493b 100644 --- a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ApiMessageHttpRequestTest.java +++ b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ApiMessageHttpRequestTest.java @@ -143,6 +143,9 @@ public String getFieldValue(String s) { HttpRequest httpRequest = httpRequestRunnable.createHttpRequest(); String expectedUrl = ENDPOINT + "name/tree_frog" + "?requestId=request57"; Truth.assertThat(httpRequest.getUrl().toString()).isEqualTo(expectedUrl); + Truth.assertThat(httpRequest.getHeaders().getContentLength()) + .isEqualTo(httpRequest.getContent().getLength()); + Truth.assertThat(httpRequest.getHeaders().getContentLength()).isGreaterThan((long) 0); OutputStream outputStream = new PrintableOutputStream(); httpRequest.getContent().writeTo(outputStream); From 257ba1337e6bc63a2e16e5018c1943885efb7a62 Mon Sep 17 00:00:00 2001 From: Andrea Lin Date: Wed, 30 Jan 2019 14:42:01 -0800 Subject: [PATCH 2/2] just set Content body to EmptyContent --- .../api/gax/httpjson/HttpJsonStatusCode.java | 4 +++ .../api/gax/httpjson/HttpRequestRunnable.java | 30 ++++--------------- .../httpjson/ApiMessageHttpRequestTest.java | 3 -- .../gax/httpjson/HttpRequestRunnableTest.java | 2 ++ 4 files changed, 12 insertions(+), 27 deletions(-) diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonStatusCode.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonStatusCode.java index 60374761d..7ad2df820 100644 --- a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonStatusCode.java +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonStatusCode.java @@ -80,6 +80,10 @@ static StatusCode.Code httpStatusToStatusCode(int httpStatus, String errorMessag } else { return Code.ABORTED; } + case 411: + throw new IllegalStateException( + "411 status code received (Content-Length header not given.) Please file a bug against https://github.com/googleapis/gax-java/\n" + + httpStatus); case 429: return Code.RESOURCE_EXHAUSTED; case 499: diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java index 79d11103a..1c449dca5 100644 --- a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpRequestRunnable.java @@ -29,6 +29,7 @@ */ package com.google.api.gax.httpjson; +import com.google.api.client.http.EmptyContent; import com.google.api.client.http.GenericUrl; import com.google.api.client.http.HttpContent; import com.google.api.client.http.HttpMediaType; @@ -52,7 +53,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import javax.annotation.Nullable; /** A runnable object that creates and executes an HTTP request. */ @AutoValue @@ -90,12 +90,16 @@ HttpRequest createHttpRequest() throws IOException { // Create HTTP request body. String requestBody = requestFormatter.getRequestBody(getRequest()); - JsonHttpContent jsonHttpContent = null; + HttpContent jsonHttpContent; if (!Strings.isNullOrEmpty(requestBody)) { getJsonFactory().createJsonParser(requestBody).parse(tokenRequest); jsonHttpContent = new JsonHttpContent(getJsonFactory(), tokenRequest) .setMediaType((new HttpMediaType("application/json"))); + } else { + // Force underlying HTTP lib to set Content-Length header to avoid 411s. + // See EmptyContent.java. + jsonHttpContent = new EmptyContent(); } // Populate URL path and query parameters. @@ -112,32 +116,10 @@ HttpRequest createHttpRequest() throws IOException { for (HttpJsonHeaderEnhancer enhancer : getHeaderEnhancers()) { enhancer.enhance(httpRequest.getHeaders()); } - - // Set Content-Length header to avoid 411s. - HttpJsonHeaderEnhancer contentLengthHeader = getContentLengthHeader(jsonHttpContent); - if (contentLengthHeader != null) { - contentLengthHeader.enhance(httpRequest.getHeaders()); - } - httpRequest.setParser(new JsonObjectParser(getJsonFactory())); return httpRequest; } - @Nullable - private HttpJsonHeaderEnhancer getContentLengthHeader(@Nullable HttpContent requestBody) { - long contentLength = 0; - try { - if (requestBody != null) { - contentLength = requestBody.getLength(); - } - } catch (IOException e) { - // Could not determine content length. - return null; - } - - return HttpJsonHeaderEnhancers.create("Content-Length", String.valueOf(contentLength)); - } - @Override public void run() { try { diff --git a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ApiMessageHttpRequestTest.java b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ApiMessageHttpRequestTest.java index 5477e493b..05e99fbe4 100644 --- a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ApiMessageHttpRequestTest.java +++ b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ApiMessageHttpRequestTest.java @@ -143,9 +143,6 @@ public String getFieldValue(String s) { HttpRequest httpRequest = httpRequestRunnable.createHttpRequest(); String expectedUrl = ENDPOINT + "name/tree_frog" + "?requestId=request57"; Truth.assertThat(httpRequest.getUrl().toString()).isEqualTo(expectedUrl); - Truth.assertThat(httpRequest.getHeaders().getContentLength()) - .isEqualTo(httpRequest.getContent().getLength()); - Truth.assertThat(httpRequest.getHeaders().getContentLength()).isGreaterThan((long) 0); OutputStream outputStream = new PrintableOutputStream(); httpRequest.getContent().writeTo(outputStream); diff --git a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpRequestRunnableTest.java b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpRequestRunnableTest.java index e92f1ad8a..1da36dd8d 100644 --- a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpRequestRunnableTest.java +++ b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpRequestRunnableTest.java @@ -29,6 +29,7 @@ */ package com.google.api.gax.httpjson; +import com.google.api.client.http.EmptyContent; import com.google.api.client.http.HttpRequest; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.client.testing.http.MockHttpTransport; @@ -161,6 +162,7 @@ public String serialize(Void response) { @Test public void testRequestUrl() throws IOException { HttpRequest httpRequest = httpRequestRunnable.createHttpRequest(); + Truth.assertThat(httpRequest.getContent()).isInstanceOf(EmptyContent.class); String expectedUrl = ENDPOINT + "name/feline" + "?food=bird&food=mouse&size=small"; Truth.assertThat(httpRequest.getUrl().toString()).isEqualTo(expectedUrl); }