You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by "Godbey, David J. (HQ-LM020)[DIGITAL MANAGEMENT INC.]" <da...@nasa.gov> on 2012/11/05 22:06:50 UTC
Servlet getInputStream getting truncated
This is probably a good place to pose this question. I'm guessing someone will know what is going on, and perhaps http-client has a solution.
You will recall that recently I created a "proxy" servlet to deal with NTLMv2 authentication because not java nor jaxws can manage NTLMv2 authentication. http-client provides the authentication layer for me, and that is working perfectly.
Now I have a new problem. When the servlet payload gets too large (and not all that large, mind you) the input stream gets truncated and the Exchange EWS request fails. Here are the details, see code below if needed:
The request.getContentLenght() method returns 9,219 bytes.
When I unload the request.getInputStream() into the buffer and count the bytes the logger.debug spits out, I count 7,776 bytes. And indeed, the SOAP XML package is malformed. What happened to the other 1,443 bytes?
App server=JBoss 5.1.
Anyone know what is going on and how to fix it?
Thanks,
Dave
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(CONTENT_XML);
PrintWriter out = response.getWriter();
try {
int len = request.getContentLength();
byte[ ] buf = new byte[len];
_logger.debug("SOAP request length="+len+" buffer size="+buf.length);
BufferedInputStream in = new BufferedInputStream(request.getInputStream(), len);
in.read(buf, 0, len);
_logger.debug("SOAP resquest :");
_logger.debug(new String(buf));
String soap = doEws(buf, request);
_logger.debug("SOAP response :");
_logger.debug(soap);
out.print(soap);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
out.close();
}
}
private String doEws(byte[] inSoap, HttpServletRequest r) {
DefaultHttpClient httpclient = new DefaultHttpClient();
String soap = "";
try {
String localIp = Inet4Address.getLocalHost().getHostAddress();
HttpHost httpHost = new HttpHost(_host, 443, "https");
httpclient.getCredentialsProvider().setCredentials(new
AuthScope(httpHost), new NTCredentials(_user, _password,
localIp, _domain));
AuthCache authCache = new BasicAuthCache();
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "UTF-8");
HttpProtocolParams.setUseExpectContinue(params, true);
NTLMSchemeFactory nsf = new NTLMSchemeFactory();
AuthScheme authScheme = nsf.newInstance(params);
authCache.put(httpHost, authScheme);
// Add AuthCache to the execution context
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
HttpPost http = new HttpPost(_serviceEndpoint);
for (Enumeration en=r.getHeaderNames();en.hasMoreElements();) {
String name = (String) en.nextElement();
if (!(name.equals("host") || name.equals("authorization") ||
name.equals("content-length"))) {
_logger.debug("Adding header="+name);
try {
http.addHeader(name, r.getHeader(name));
} catch (Exception e) {
// Don't worry, keep going
}
}
}
http.setEntity(new ByteArrayEntity(inSoap));
HttpResponse response = httpclient.execute(httpHost, http,
localcontext);
HttpEntity entity = response.getEntity();
if (entity != null) {
soap = EntityUtils.toString(entity);
}
EntityUtils.consume(entity);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
httpclient.getConnectionManager().shutdown();
}
return soap;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org
Re: Servlet getInputStream getting truncated
Posted by Oleg Kalnichevski <ol...@apache.org>.
On Mon, 2012-11-05 at 15:06 -0600, Godbey, David J. (HQ-LM020)[DIGITAL
MANAGEMENT INC.] wrote:
> This is probably a good place to pose this question. I'm guessing someone will know what is going on, and perhaps http-client has a solution.
>
> You will recall that recently I created a "proxy" servlet to deal with NTLMv2 authentication because not java nor jaxws can manage NTLMv2 authentication. http-client provides the authentication layer for me, and that is working perfectly.
>
> Now I have a new problem. When the servlet payload gets too large (and not all that large, mind you) the input stream gets truncated and the Exchange EWS request fails. Here are the details, see code below if needed:
>
> The request.getContentLenght() method returns 9,219 bytes.
> When I unload the request.getInputStream() into the buffer and count the bytes the logger.debug spits out, I count 7,776 bytes. And indeed, the SOAP XML package is malformed. What happened to the other 1,443 bytes?
>
> App server=JBoss 5.1.
>
> Anyone know what is going on and how to fix it?
> Thanks,
> Dave
>
> public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
> response.setContentType(CONTENT_XML);
> PrintWriter out = response.getWriter();
> try {
> int len = request.getContentLength();
> byte[ ] buf = new byte[len];
> _logger.debug("SOAP request length="+len+" buffer size="+buf.length);
> BufferedInputStream in = new BufferedInputStream(request.getInputStream(), len);
> in.read(buf, 0, len);
I believe the way you are reading message content is wrong.
InputStream#read() method is not guaranteed to return the request amount
of data. The operation can terminate as soon as there is _some_ data to
be read
0 < n <= len
Not to mention that request#getContentLength() can return -1 in case the
message body is chunk coded.
So, one must read from the stream in a loop until a read operation
terminates with -1 (end of stream).
> _logger.debug("SOAP resquest :");
> _logger.debug(new String(buf));
> String soap = doEws(buf, request);
> _logger.debug("SOAP response :");
> _logger.debug(soap);
> out.print(soap);
> } catch (Exception e) {
> throw new RuntimeException(e);
> } finally {
> out.close();
> }
> }
>
> private String doEws(byte[] inSoap, HttpServletRequest r) {
> DefaultHttpClient httpclient = new DefaultHttpClient();
> String soap = "";
> try {
> String localIp = Inet4Address.getLocalHost().getHostAddress();
> HttpHost httpHost = new HttpHost(_host, 443, "https");
> httpclient.getCredentialsProvider().setCredentials(new
> AuthScope(httpHost), new NTCredentials(_user, _password,
> localIp, _domain));
>
> AuthCache authCache = new BasicAuthCache();
> HttpParams params = new BasicHttpParams();
> HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
> HttpProtocolParams.setContentCharset(params, "UTF-8");
> HttpProtocolParams.setUseExpectContinue(params, true);
>
> NTLMSchemeFactory nsf = new NTLMSchemeFactory();
> AuthScheme authScheme = nsf.newInstance(params);
> authCache.put(httpHost, authScheme);
>
NTLM auth scheme cannot be used preemptively. There is no point caching
it.
> // Add AuthCache to the execution context
> BasicHttpContext localcontext = new BasicHttpContext();
> localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
>
> HttpPost http = new HttpPost(_serviceEndpoint);
> for (Enumeration en=r.getHeaderNames();en.hasMoreElements();) {
> String name = (String) en.nextElement();
> if (!(name.equals("host") || name.equals("authorization") ||
> name.equals("content-length"))) {
> _logger.debug("Adding header="+name);
> try {
> http.addHeader(name, r.getHeader(name));
> } catch (Exception e) {
> // Don't worry, keep going
> }
> }
> }
> http.setEntity(new ByteArrayEntity(inSoap));
>
> HttpResponse response = httpclient.execute(httpHost, http,
> localcontext);
> HttpEntity entity = response.getEntity();
>
> if (entity != null) {
> soap = EntityUtils.toString(entity);
> }
> EntityUtils.consume(entity);
>
> } catch (Exception e) {
> throw new RuntimeException(e);
> } finally {
> httpclient.getConnectionManager().shutdown();
> }
> return soap;
> }
>
You might want to consider reusing HttpClient instance in order to
improve performance and resource utilization.
Hope this helps
Oleg
---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org