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: [email protected]
For additional commands, e-mail: [email protected]