Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 64734 invoked from network); 13 Feb 2008 11:57:39 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 13 Feb 2008 11:57:39 -0000 Received: (qmail 90446 invoked by uid 500); 13 Feb 2008 11:57:33 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 90388 invoked by uid 500); 13 Feb 2008 11:57:33 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 90377 invoked by uid 99); 13 Feb 2008 11:57:33 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Feb 2008 03:57:33 -0800 X-ASF-Spam-Status: No, hits=-1998.5 required=10.0 tests=ALL_TRUSTED,WEIRD_PORT X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Feb 2008 11:57:10 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 324F01A9832; Wed, 13 Feb 2008 03:57:17 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r627366 - in /geronimo/sandbox/AsyncHttpClient/src: main/java/org/apache/ahc/codec/ test/java/org/apache/ahc/ Date: Wed, 13 Feb 2008 11:57:13 -0000 To: scm@geronimo.apache.org From: rickmcguire@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080213115717.324F01A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: rickmcguire Date: Wed Feb 13 03:57:11 2008 New Revision: 627366 URL: http://svn.apache.org/viewvc?rev=627366&view=rev Log: GERONIMO-3839 some request headers may be added twice Patch provided by Sangjin Lee Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpMessage.java geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestEncoder.java geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java?rev=627366&r1=627365&r2=627366&view=diff ============================================================================== --- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java (original) +++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java Wed Feb 13 03:57:11 2008 @@ -150,10 +150,11 @@ request.setUrl(new URL(response.getLocation())); // if we're redirected via 30x, the request method should be reset to GET if (!request.getRequestMethod().equals(HttpRequestMessage.REQUEST_GET)) { - request.setRequestMethod(HttpRequestMessage.REQUEST_GET); + request.setRequestMethod(HttpRequestMessage.REQUEST_GET); } - // we also need to clear out the parameters + // we also need to clear out the parameters and the content request.clearAllParameters(); + request.clearContent(); //Send the redirect client.sendRequest(request); Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpMessage.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpMessage.java?rev=627366&r1=627365&r2=627366&view=diff ============================================================================== --- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpMessage.java (original) +++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpMessage.java Wed Feb 13 03:57:11 2008 @@ -103,6 +103,16 @@ this.content.write(byteContent); } + + /** + * Removes content, if any. + */ + public void clearContent() { + // simply nulling the content will do + if (content != null) { + content = null; + } + } /** * Gets the cookies. Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestEncoder.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestEncoder.java?rev=627366&r1=627365&r2=627366&view=diff ============================================================================== --- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestEncoder.java (original) +++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestEncoder.java Wed Feb 13 03:57:11 2008 @@ -49,8 +49,8 @@ /** The Constant CRLF. */ private static final byte[] CRLF = new byte[] {0x0D, 0x0A}; - /** The Constant POST_CONTENT_TYPE. */ - private static final String POST_CONTENT_TYPE = "application/x-www-form-urlencoded"; + /** The Constant FORM_POST_CONTENT_TYPE. */ + private static final String FORM_POST_CONTENT_TYPE = "application/x-www-form-urlencoded"; static { Set> types = new HashSet>(); @@ -104,9 +104,10 @@ } CharsetEncoder encoder = Charset.forName(HttpMessage.HTTP_ELEMENT_CHARSET).newEncoder(); - buf.putString(msg.getRequestMethod(), encoder); + String method = msg.getRequestMethod(); + buf.putString(method, encoder); buf.putString(" ", encoder); - if (msg.getRequestMethod().equals(HttpRequestMessage.REQUEST_CONNECT)) { + if (method.equals(HttpRequestMessage.REQUEST_CONNECT)) { buf.putString(msg.getHost(), encoder); buf.putString(":", encoder); buf.putString(msg.getPort() + "", encoder); @@ -117,7 +118,7 @@ buf.putString(msg.getUrl().getFile(), encoder); } //If its a GET, append the attributes - if (msg.getRequestMethod().equals(HttpRequestMessage.REQUEST_GET) && attrCount > 0) { + if (method.equals(HttpRequestMessage.REQUEST_GET) && attrCount > 0) { //If there is not already a ? in the query, append one, otherwise append a & if (!msg.getUrl().getFile().contains("?")) { buf.putString("?", encoder); @@ -131,20 +132,57 @@ buf.put(CRLF); //This header is required for HTTP/1.1 - buf.putString("Host: ", encoder); - buf.putString(msg.getHost(), encoder); + + String hostHeader = msg.getHost(); if ((msg.getProtocol().equals("http") && msg.getPort() != 80) || (msg.getProtocol().equals("https") && msg.getPort() != 443)) { - buf.putString(":", encoder); - buf.putString(msg.getPort() + "", encoder); + hostHeader += ":" + msg.getPort(); } - buf.put(CRLF); - + // set the host header, removing any Host header that might already exist. + msg.setHeader("Host", hostHeader); + //User agent if (msg.getUserAgent() != null) { - buf.putString("User-Agent: ", encoder); - buf.putString(msg.getUserAgent(), encoder); - buf.put(CRLF); + msg.setHeader("User-Agent", msg.getUserAgent()); + } + + // potentially for a POST request. We need to obtain the content information + // so we can add the content headers...but the attaching of the content comes later. + byte content[] = null; + + // If this is a POST and parameters are provided, this is a form + // post; any existing content is an error and will be ignored and + // the content type will be set accordingly + if (method.equals(HttpRequestMessage.REQUEST_POST) && attrCount > 0) { + content = urlAttrs.getBytes(); + + // these override any headers that might already be in the set + msg.setHeader(HttpMessage.CONTENT_TYPE, FORM_POST_CONTENT_TYPE); + } else if (msg.getContent() != null) { + // if the message body was provided by the caller, then use it + // (as long as the method is not among the types for which + // entities are disallowed) + if (!method.equals(HttpRequestMessage.REQUEST_TRACE) && + !method.equals(HttpRequestMessage.REQUEST_CONNECT)) { + content = msg.getContent(); + } + } + + // set the proper content length header + if (content != null && content.length > 0) { + msg.setHeader(HttpMessage.CONTENT_LENGTH, String.valueOf(content.length)); + } else { + // remove any existing content related headers + msg.removeHeader(HttpMessage.CONTENT_TYPE); + msg.removeHeader(HttpMessage.CONTENT_LENGTH); + } + + //Process authentication + AuthState state = msg.getAuthState(); + if (state != null){ + String auth = state.getAuthScheme().authenticate(msg.getCredential(new AuthScope(msg.getHost(), msg.getPort(), state.getAuthScheme().getRealm())),msg); + msg.setHeader("Authorization", auth); + state.setAuthAttempted(true); } //Process any headers we have @@ -156,29 +194,13 @@ //to handle these issues for the request processCookies(msg, buf, encoder); - //If this is a POST, then we need a content length and type - if (msg.getRequestMethod().equals(HttpRequestMessage.REQUEST_POST)) { - byte content[] = urlAttrs.getBytes(); - - //Type - buf.putString(HttpMessage.CONTENT_TYPE, encoder); - buf.putString(": ", encoder); - buf.putString(POST_CONTENT_TYPE, encoder); - buf.put(CRLF); - - //Length - buf.putString(HttpMessage.CONTENT_LENGTH, encoder); - buf.putString(": ", encoder); - buf.putString(content.length + "", encoder); - buf.put(CRLF); - //Blank line - buf.put(CRLF); + //Blank line indicates end of the headers + buf.put(CRLF); + + //If this is a POST, then we have content to attach after the blank line + if (content != null) { buf.put(content); - } else { - //Blank line - buf.put(CRLF); - } - + } } catch (CharacterCodingException ex) { ex.printStackTrace(); } Modified: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java?rev=627366&r1=627365&r2=627366&view=diff ============================================================================== --- geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java (original) +++ geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java Wed Feb 13 03:57:11 2008 @@ -117,6 +117,9 @@ msg = callback.getMessage(); assertEquals(302, msg.getStatusCode()); assertEquals(msg.getLocation(), "http://localhost:8282/index.jsp"); + // the monitor events are dispatched asynchronously, so give a little time + // for them all to be dispatched. + Thread.sleep(500); assertEquals(counter.getCount(MonitoringEvent.REQUEST_STARTED), 1); assertEquals(counter.getCount(MonitoringEvent.REQUEST_COMPLETED), 1); @@ -128,7 +131,7 @@ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_SUCCESSFUL), 1); assertEquals(counter.getCount(MonitoringEvent.REQUEST_REDIRECTED), 0); assertEquals(counter.getCount(MonitoringEvent.REQUEST_CHALLENGED), 0); - assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED_BY_SERVER), 0); + assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED_BY_SERVER), 1); assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED), 0); }