0

Im trying to get data from a datalogger using Http/1.1 GET method but the response contains only http body with no header. Im getting the following exception:

Exception in thread "main" org.apache.http.client.ClientProtocolException
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:909)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1066)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1044)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1035)
    at Main.main(Main.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.apache.http.ProtocolException: The server failed to respond with a valid HTTP response
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:103)
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62)
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254)
    at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289)
    at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252)
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191)
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127)
    at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:712)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:517)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    ... 9 more

Code:

DefaultHttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://xxx.xxxxxxx.xxx");
request.setHeader("Connection", "close");
client.execute(request);

Terminal:

telnet xxx.xxxxxxx.xxx 80
Trying xxx.xxxxxxx.xxx...
Connected to xxx.xxxxxxx.xxx.
Escape character is '^]'.
GET /api/1.0/getData?preserve=true HTTP/1.1
Host: xxx.xxxxxxx.xxx
Connection: close
User-Agent: Apache-HttpClient/4.2.1 (java 1.5)

{"name":"DEI2","id":"00d0694318ac","fw":"1.0.23","data":[]}
Connection closed by foreign host.

Is there a way to skip the Http response header processing and just process the response body?

4
  • The response is not valid http if it doesn't contain a status line and headers. You can't use an http client to process it. Commented Apr 2, 2014 at 20:26
  • I know, Im wondering if I can use it with some workaround to avoid writing raw socket code. Commented Apr 2, 2014 at 20:31
  • No, you cannot. The handling code is too embedded into the library and is probably not worth it. Fix your server. Commented Apr 2, 2014 at 20:50
  • This is the problem... I cant fix it, its a closed source electronic datalogger. Commented Apr 2, 2014 at 21:32

1 Answer 1

1

Not that I consider this approach a good idea but this is how this can be done with Apache HttpClient


static class CustomHttpConnection extends DefaultBHttpClientConnection {

    public CustomHttpConnection(final int buffersize) {
        super(buffersize);
    }

    @Override
    public SessionInputBuffer getSessionInputBuffer() {
        return super.getSessionInputBuffer();
    }
}

// Create protocol processor
HttpProcessor processor = HttpProcessorBuilder.create()
        .addAll(new RequestContent(),
                new RequestTargetHost(),
                new RequestConnControl(),
                new RequestUserAgent("HTTP/1.1"))
        .build();

// Target host
InetSocketAddress target = new InetSocketAddress("localhost", 8080);

// Create custom connection that exposes its session input buffer
CustomHttpConnection conn = new CustomHttpConnection(10 * 1024);
try {

    // Open socket
    Socket socket = new Socket();
    socket.connect(target, 5000);
    // Bind it to the connection
    conn.bind(socket);

    // Create and initialize request
    HttpGet request = new HttpGet("/");
    // Force connection close
    request.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);

    // Create and initialize execution context
    HttpClientContext context = HttpClientContext.create();
    context.setTargetHost(new HttpHost(target.getHostName(), target.getPort()));
    context.setRequestConfig(RequestConfig.DEFAULT);
    context.setAttribute(HttpClientContext.HTTP_REQUEST, request);
    context.setAttribute(HttpClientContext.HTTP_CONNECTION, conn);

    // Process request
    processor.process(request, context);

    // Send request
    conn.sendRequestHeader(request);
    if (request instanceof HttpEntityEnclosingRequest) {
        conn.sendRequestEntity(((HttpEntityEnclosingRequest) request));
    }
    conn.flush();

    SessionInputBuffer connSessionInputBuffer = conn.getSessionInputBuffer();
    IdentityInputStream instream = new IdentityInputStream(connSessionInputBuffer);
    int l;
    byte[] buff = new byte[1024];
    while ((l = instream.read(buff)) != -1) {
        System.out.println(new String(buff, 0, l, Consts.ASCII));
    }
} finally {
    conn.close();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.