title: java.net.SocketException: Unexpected end of file from server using Spring's RestTemplate
body: <p>I've already checked several questions / answers regarding similar subjects, but can't find the proper answer for my case.</p>
  
  <p>I'm using Spring's RestTemplate but fails to get the response from a third party  server with the following exception:</p>
  
  <pre><code>Exception in thread "main" org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://64.76.157.19:8283/ENAP/ProveedorExterno/v1.0/insertarUltimaPosicion":Unexpected end of file from server; nested exception is java.net.SocketException: Unexpected end of file from server
      at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:567)
      at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:512)
      at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:454)
      at cl.waypoint.integracion.GenericCallback.sendEnap(GenericCallback.java:187)
      at cl.waypoint.integracion.GenericCallback.main(GenericCallback.java:167)
  Caused by: java.net.SocketException: Unexpected end of file from server
      at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:718)
      at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:579)
      at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1322)
      at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
      at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:48)
      at cl.waypoint.integracion.GenericCallback$LoggingRequestInterceptor.log(GenericCallback.java:229)
      at cl.waypoint.integracion.GenericCallback$LoggingRequestInterceptor.intercept(GenericCallback.java:216)
      at org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:84)
      at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:69)
      at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
      at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
      at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:551)
      ... 4 more
  </code></pre>
  
  <p>But when sending the same request/headers/payload using command line curl there seems to be no problem at all, this is the verbose output of it:</p>
  
  <pre><code>*   Trying A.B.C.D...
  * Connected to A.B.C.D (A.B.C.D) port 8283 (#0)
  &gt; POST /ENAP/ProveedorExterno/v1.0/insertarUltimaPosicion HTTP/1.1
  &gt; Host: A.B.C.D:8283
  &gt; User-Agent: curl/7.43.0
  &gt; Accept: */*
  &gt; Content-Type: application/json
  &gt; Authorization: Bearer dsgfsdgf786dsfg7dsgf
  &gt; Content-Length: 567
  &gt; 
  * upload completely sent off: 567 out of 567 bytes
  &lt; HTTP/1.1 200 OK
  &lt; Access-Control-Allow-Origin: *
  &lt; Access-Control-Allow-Methods: POST
  &lt; Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Content-Type
  &lt; Content-Type: application/json
  &lt; Date: Wed, 27 Jul 2016 13:35:26 GMT
  &lt; Transfer-Encoding: chunked
  &lt; 
  * Connection #0 to host 64.76.157.19 left intact
  </code></pre>
  
  <p>PS: Authorization token and server's IP address have been changed for security reasons.</p>
  
  <p>Spring seems to hang for a while and then then throw the exception, perhaps it's waiting for something by default...Content-Length header on the response? If so, can that be overriden?</p>
  
  <p>The Exception comes from the following interceptor:</p>
  
  <pre><code>class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {
  
      @Override
      public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
              throws IOException {
  
          ClientHttpResponse response = execution.execute(request, body);
  
          log(request, body, response);
  
          return response;
      }
  
      private void log(HttpRequest request, byte[] body, ClientHttpResponse response) throws IOException {
          HttpHeaders headers = request.getHeaders();
          System.out.println("=============================");
          for (Entry&lt;String, List&lt;String&gt;&gt; header : headers.entrySet()) {
              System.out.println(header.getKey() + ": " + header.getValue());
          }
          System.out.println("=============================");
          System.out.println(new String(body));
          System.out.println(response.getRawStatusCode());
          System.out.println(response.getStatusText());
  
      }
  }
  </code></pre>
  
  <p>Which is used from the following code snippet:</p>
  
  <pre><code>private void sendEnap(String patente, String fecha, String latitud, String longitud, BigInteger sentido,
          BigInteger velocidad, int ignicion) {
      RestTemplate restTemplate = new RestTemplate();
      // set interceptors/requestFactory
      ClientHttpRequestInterceptor ri = new LoggingRequestInterceptor();
      List&lt;ClientHttpRequestInterceptor&gt; ris = new ArrayList&lt;ClientHttpRequestInterceptor&gt;();
      ris.add(ri);
      restTemplate.setInterceptors(ris);
  
      MultiValueMap&lt;String, String&gt; headers = new LinkedMultiValueMap&lt;String, String&gt;();
      headers.add("Authorization", "Bearer " + ENANGAB_TOKEN);
      headers.add("Content-Type", MediaType.APPLICATION_JSON.toString());
      headers.add("User-Agent", "Waypoint");
      EnapRequest enapRequest = new EnapRequest(patente, fecha, latitud, longitud, sentido, velocidad, ignicion);
      HttpEntity&lt;EnapRequest&gt; request = new HttpEntity&lt;EnapRequest&gt;(enapRequest, headers);
  
      ResponseEntity&lt;EnapResponse&gt; response = restTemplate.exchange(ENAP_ENDPOINT, HttpMethod.POST, request,
              EnapResponse.class);
      System.out.println(response.getBody());
  
  }
  </code></pre>
  
  <p>If the interceptor is disabled, same exception arises but now with this stacktrace:</p>
  
  <pre><code>Exception in thread "main" org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://64.76.157.19:8283/ENAP/ProveedorExterno/v1.0/insertarUltimaPosicion":Unexpected end of file from server; nested exception is java.net.SocketException: Unexpected end of file from server
      at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:567)
      at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:512)
      at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:454)
      at cl.waypoint.integracion.GenericCallback.sendEnap(GenericCallback.java:187)
      at cl.waypoint.integracion.GenericCallback.main(GenericCallback.java:167)
  Caused by: java.net.SocketException: Unexpected end of file from server
      at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:718)
      at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:579)
      at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1322)
      at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
      at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:48)
      at org.springframework.http.client.AbstractClientHttpResponse.getStatusCode(AbstractClientHttpResponse.java:33)
      at org.springframework.web.client.DefaultResponseErrorHandler.getHttpStatusCode(DefaultResponseErrorHandler.java:56)
      at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:50)
      at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:552)
      ... 4 more
  </code></pre>
  
  <p>The above is another hint for a missing header on the response, don't know which one, and how to avoid such wait too.</p>
  
  <p>Any hints would be appreciated</p>
  
  <p>EDIT:</p>
  
  <p>Headers sent:</p>
  
  <pre><code>Accept: [application/json, application/*+json]
  Authorization: [Bearer dsgfsdgf786dsfg7dsgf]
  Content-Type: [application/json]
  User-Agent: [Waypoint]
  Content-Length: [567]
  </code></pre>
  
  <p>EnapRequest class:
      package cl.waypoint.integracion;</p>
  
  <pre><code>import java.math.BigInteger;
  
  import com.fasterxml.jackson.annotation.JsonProperty;
  
  public class EnapRequest {
  
      @JsonProperty("token_proveedor")
      private String tokenProveedor = GenericCallback.ENANGAB_TOKEN;
      private Posicion[] posicion;
  
      public EnapRequest(String patente, String fecha, String latitud, String longitud, BigInteger sentido,
              BigInteger velocidad, int  ignicion) {
          posicion = new Posicion[1];
          posicion[0] = new Posicion(patente, fecha, latitud, longitud, sentido, velocidad, ignicion);
      }
  
      public String getTokenProveedor() {
          return tokenProveedor;
      }
  
      public void setTokenProveedor(String tokenProveedor) {
          this.tokenProveedor = tokenProveedor;
      }
  
      public Posicion[] getPosicion() {
          return posicion;
      }
  
      public void setPosicion(Posicion[] posicion) {
          this.posicion = posicion;
      }
  }
  </code></pre>
  
  <p>The request body is in fact being sent as JSON (exactly the same as with curl, pretty print here for improved reading):</p>
  
  <pre><code>{
    "posicion": [
      {
        "patente": "AB1234",
        "latitud": "-36.752752",
        "longitud": "-73.0804947",
        "direccion": "120",
        "velocidad": "65",
        "transportista": "ENANGAB",
        "sensora1": null,
        "sensora2": null,
        "sensora3": null,
        "mopo_sensord1": null,
        "mopo_sensord2": null,
        "mopo_sensord3": null,
        "mopo_sensord4": null,
        "mopo_sensord5": null,
        "mopo_sensord6": null,
        "opcional1": null,
        "opcional2": null,
        "opcional3": null,
        "opcional4": null,
        "codigo_interno": null,
        "fecha_hora": "2016-07-15T14:24:00",
        "mopo_estado": "1",
        "mopo_estado_ignicion": "1",
        "moev_numero_evento": "45"
      }
    ],
    "token_proveedor": "dsgfsdgf786dsfg7dsgf"
  }
  </code></pre>
  
  <p>The RestTemplate object has already configured support for the following converters:</p>
  
  <pre><code>class org.springframework.http.converter.ByteArrayHttpMessageConverter
  class org.springframework.http.converter.StringHttpMessageConverter
  class org.springframework.http.converter.ResourceHttpMessageConverter
  class org.springframework.http.converter.xml.SourceHttpMessageConverter
  class org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter
  class org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter
  class org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
  </code></pre>