How to configure HTTPServer to use content length and not transfer encoding: chunked?
Asked Answered
A

1

1

I'm using java's HTTP Server object with web service implemeted by WebServiceProvider. I see that no matter of the client request, the answer is chunked and i need it to be with content length. so i'm assuming the problem is in the server and not the web server provider, right? and how can i configure the http header to use content length and not chunked?

    HttpServer m_server = HttpServer.create();
    Endpoint ep= Endpoint.create(new ep());
    HttpContext epContext = m_server.createContext("/DownloadFile");
    ep.publish(downloadFileContext);
Arrio answered 2/8, 2011 at 20:14 Comment(0)
F
1

I assume you're talking about the com.sun.net.httpserver HTTPServer. I further assume that you're connecting the server to the service with a call to Endpoint.publish, using some service provider which supports HTTPServer.

The key is in the HttpExchange.sendResponseHeaders method:

If the response length parameter is greater than zero, this specifies an exact number of bytes to send and the application must send that exact amount of data. If the response length parameter is zero, then chunked transfer encoding is used and an arbitrary amount of data may be sent. The application terminates the response body by closing the OutputStream.

So, as long as the handler is passing a positive value for responseLength, Content-Length is used. Of course, to do that, it will have to know how much data it is going to send ahead of time, which it might well not. Whether it does or not depends entirely on the implementation of the binding, i'm afraid. I don't believe this is standardised - indeed, i don't believe that the WebServiceProvider/HTTPServer is standardised at all.

However, even if your provider is uncooperative, you have a recourse: write a Filter which adds buffering, and add it to the HttpContext which you are using to publish the service. I think that to do this, you would have to write an implementation of HttpExchange which buffers the data written to it, pass that down the filter chain for the handler to write its response to, then when it comes back, write the buffered content, setting the responseLength when it does so.

Freedom answered 2/8, 2011 at 20:26 Comment(5)
Hi. it sounds abour right, but i have web services which are published as endpoints related so some context on the server, so i don't actually mange any responses via the server itself, the response is sent from the web service.Arrio
@Sophie: I don't understand, sorry. Are you saying you don't control the code which publishes the web services to the HTTPServer? Could you edit your questions with some more details about how your code works, and what bits of it you can change?Freedom
i have added a code example. the "ep" is the web service i have. so when client executes ip_add/DownloadFile it goes to my web service. i also do know the length of the data to be sent.Arrio
I see (although i assume 'downloadFileContext' should be 'epContext'). Sadly, although you might know the length of the response, the web service binding doesn't, and it's the binding that is interacting with the HttpExchange. But because you have access to the HttpContext, you can write a Filter which buffers the output as i explained, and add that to the context (epContext.getFilters().add(new BufferingFilter())). Alternatively, you could write a Filter which sets the response length and doesn't do buffering, but that will cause an error if you are wrong about the length, which is risky.Freedom
I succeeded to get the httpExchnage from the WebServiceContext and call HttpExchange.sendResponseHeaders on it. so now i see the Content-Length in the HTTP message, but the message itself is not recieved by the client - no payload is sent. any ides how can i proceed?Arrio

© 2022 - 2024 — McMap. All rights reserved.