Index: httpcore/module-main/src/test/java/org/apache/http/protocol/TestStandardInterceptors.java =================================================================== --- httpcore/module-main/src/test/java/org/apache/http/protocol/TestStandardInterceptors.java (revision 504180) +++ httpcore/module-main/src/test/java/org/apache/http/protocol/TestStandardInterceptors.java (working copy) @@ -48,6 +48,7 @@ import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.apache.http.params.HttpProtocolParams; +import org.apache.http.impl.EnglishReasonPhraseCatalog; /** * @author Oleg Kalnichevski @@ -444,7 +445,7 @@ public void testResponseConnControlNoEntity() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); ResponseConnControl interceptor = new ResponseConnControl(); interceptor.process(response, context); Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE); @@ -453,7 +454,7 @@ public void testResponseConnControlEntityContentLength() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); StringEntity entity = new StringEntity("whatever"); response.setEntity(entity); ResponseConnControl interceptor = new ResponseConnControl(); @@ -467,7 +468,7 @@ BasicHttpRequest request = new BasicHttpRequest("GET", "/"); request.addHeader(new BasicHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE)); context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); BasicHttpEntity entity = new BasicHttpEntity(); response.setEntity(entity); ResponseConnControl interceptor = new ResponseConnControl(); @@ -479,7 +480,7 @@ public void testResponseConnControlEntityChunked() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); BasicHttpEntity entity = new BasicHttpEntity(); entity.setChunked(true); response.setEntity(entity); @@ -496,7 +497,7 @@ context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request); BasicHttpResponse response = new BasicHttpResponse( - HttpVersion.HTTP_1_0, HttpStatus.SC_OK); + HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK"); BasicHttpEntity entity = new BasicHttpEntity(); response.setEntity(entity); ResponseConnControl interceptor = new ResponseConnControl(); @@ -512,7 +513,7 @@ request.addHeader(new BasicHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE)); context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); StringEntity entity = new StringEntity("whatever"); response.setEntity(entity); ResponseConnControl interceptor = new ResponseConnControl(); @@ -527,7 +528,7 @@ BasicHttpRequest request = new BasicHttpRequest("GET", "/"); context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); StringEntity entity = new StringEntity("whatever"); response.setEntity(entity); ResponseConnControl interceptor = new ResponseConnControl(); @@ -556,7 +557,10 @@ for (int i = 0; i < statusCodes.length; i++) { BasicHttpResponse response = new BasicHttpResponse( - HttpVersion.HTTP_1_1, statusCodes[i]); + HttpVersion.HTTP_1_1, statusCodes[i], + EnglishReasonPhraseCatalog.INSTANCE + .getReason(statusCodes[i], null) + ); interceptor.process(response, context); Header header = response.getFirstHeader(HTTP.CONN_DIRECTIVE); assertNotNull(header); @@ -574,7 +578,7 @@ // expected } try { - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); interceptor.process(response, null); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { @@ -584,7 +588,7 @@ public void testResponseContentNoEntity() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); ResponseContent interceptor = new ResponseContent(); interceptor.process(response, context); Header header = response.getFirstHeader(HTTP.CONTENT_LEN); @@ -594,7 +598,7 @@ public void testResponseContentStatusNoContent() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.setStatusCode(HttpStatus.SC_NO_CONTENT); ResponseContent interceptor = new ResponseContent(); interceptor.process(response, context); @@ -604,7 +608,7 @@ public void testResponseContentStatusResetContent() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.setStatusCode(HttpStatus.SC_RESET_CONTENT); ResponseContent interceptor = new ResponseContent(); interceptor.process(response, context); @@ -614,7 +618,7 @@ public void testResponseContentStatusNotModified() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.setStatusCode(HttpStatus.SC_NOT_MODIFIED); ResponseContent interceptor = new ResponseContent(); interceptor.process(response, context); @@ -624,7 +628,7 @@ public void testResponseContentEntityChunked() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); BasicHttpEntity entity = new BasicHttpEntity(); entity.setChunked(true); response.setEntity(entity); @@ -639,7 +643,7 @@ public void testResponseContentEntityContentLenghtDelimited() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); BasicHttpEntity entity = new BasicHttpEntity(); entity.setContentLength (10); response.setEntity(entity); @@ -654,7 +658,7 @@ public void testResponseContentEntityUnknownContentLength() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); BasicHttpEntity entity = new BasicHttpEntity(); response.setEntity(entity); ResponseContent interceptor = new ResponseContent(); @@ -667,7 +671,7 @@ public void testResponseContentEntityChunkedHTTP10() throws Exception { HttpContext context = new HttpExecutionContext(null); - BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK); + BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK"); BasicHttpEntity entity = new BasicHttpEntity(); entity.setChunked(true); response.setEntity(entity); @@ -681,7 +685,7 @@ public void testResponseContentEntityNoContentTypeAndEncoding() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); BasicHttpEntity entity = new BasicHttpEntity(); response.setEntity(entity); ResponseContent interceptor = new ResponseContent(); @@ -694,7 +698,7 @@ public void testResponseContentEntityContentTypeAndEncoding() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); BasicHttpEntity entity = new BasicHttpEntity(); entity.setContentEncoding("whatever"); entity.setContentType("whatever"); @@ -723,7 +727,7 @@ ResponseContent interceptor = new ResponseContent(); HttpContext context = new HttpExecutionContext(null); try { - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.addHeader(new BasicHeader(HTTP.CONTENT_LEN, "10")); interceptor.process(response, context); fail("ProtocolException should have been thrown"); @@ -731,7 +735,7 @@ // expected } try { - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.addHeader(new BasicHeader(HTTP.TRANSFER_ENCODING, "stuff")); interceptor.process(response, context); fail("ProtocolException should have been thrown"); @@ -742,7 +746,7 @@ public void testResponseDateGenerated() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); ResponseDate interceptor = new ResponseDate(); interceptor.process(response, context); Header h1 = response.getFirstHeader(HTTP.DATE_DIRECTIVE); @@ -754,7 +758,7 @@ public void testResponseDateNotGenerated() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.setStatusCode(199); ResponseDate interceptor = new ResponseDate(); interceptor.process(response, context); @@ -774,7 +778,7 @@ public void testResponseServerGenerated() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.getParams().setParameter(HttpProtocolParams.ORIGIN_SERVER, "some server"); ResponseServer interceptor = new ResponseServer(); interceptor.process(response, context); @@ -785,7 +789,7 @@ public void testResponseServerNotGenerated() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.getParams().setParameter(HttpProtocolParams.ORIGIN_SERVER, "some server"); response.addHeader(new BasicHeader(HTTP.SERVER_DIRECTIVE, "whatever")); ResponseServer interceptor = new ResponseServer(); @@ -797,7 +801,7 @@ public void testResponseServerMissing() throws Exception { HttpContext context = new HttpExecutionContext(null); - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); ResponseServer interceptor = new ResponseServer(); interceptor.process(response, context); Header h1 = response.getFirstHeader(HTTP.SERVER_DIRECTIVE); Index: httpcore/module-main/src/test/java/org/apache/http/message/TestBasicMessages.java =================================================================== --- httpcore/module-main/src/test/java/org/apache/http/message/TestBasicMessages.java (revision 504180) +++ httpcore/module-main/src/test/java/org/apache/http/message/TestBasicMessages.java (working copy) @@ -66,10 +66,11 @@ } public void testDefaultResponseConstructors() { - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_BAD_REQUEST); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_BAD_REQUEST, "whatever"); assertNotNull(response.getHttpVersion()); assertEquals(HttpVersion.HTTP_1_0, response.getHttpVersion()); assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusLine().getStatusCode()); + assertEquals("whatever", response.getStatusLine().getReasonPhrase()); response = new BasicHttpResponse(new BasicStatusLine( HttpVersion.HTTP_1_1, HttpStatus.SC_INTERNAL_SERVER_ERROR, "whatever")); @@ -80,15 +81,18 @@ } public void testSetResponseStatus() { - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200); + // RW: aren't these duplicates of the constructor tests above? + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "whatever"); assertNotNull(response.getHttpVersion()); assertNotNull(response.getStatusLine()); - assertEquals(200, response.getStatusLine().getStatusCode()); + assertEquals( 200 , response.getStatusLine().getStatusCode()); + assertEquals("whatever", response.getStatusLine().getReasonPhrase()); - response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_BAD_REQUEST); + response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_BAD_REQUEST, "whatever"); assertNotNull(response.getHttpVersion()); assertEquals(HttpVersion.HTTP_1_0, response.getHttpVersion()); assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusLine().getStatusCode()); + assertEquals("whatever", response.getStatusLine().getReasonPhrase()); response = new BasicHttpResponse(new BasicStatusLine( HttpVersion.HTTP_1_1, HttpStatus.SC_INTERNAL_SERVER_ERROR, "whatever")); @@ -96,32 +100,40 @@ assertEquals(HttpVersion.HTTP_1_1, response.getHttpVersion()); assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatusLine().getStatusCode()); assertEquals("whatever", response.getStatusLine().getReasonPhrase()); - - response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + // RW: end of suspected constructor test duplicates + + response = new BasicHttpResponse + (HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); try { response.setStatusCode(-23); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected } - response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + + response = new BasicHttpResponse + (HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); try { - response.setStatusLine(null, 200); + response.setStatusLine(null, 200, "OK"); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected } - response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + + response = new BasicHttpResponse + (HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); try { response.setStatusLine(null); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected } + + // RW: there's no test of _successful_ updates } public void testSetResponseEntity() { - HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); assertNull(response.getEntity()); HttpEntity entity = new BasicHttpEntity(); Index: httpcore/module-main/src/test/java/org/apache/http/message/TestStatusLine.java =================================================================== --- httpcore/module-main/src/test/java/org/apache/http/message/TestStatusLine.java (revision 504180) +++ httpcore/module-main/src/test/java/org/apache/http/message/TestStatusLine.java (working copy) @@ -76,10 +76,6 @@ assertEquals(HttpStatus.SC_OK, statusline.getStatusCode()); assertEquals("OK", statusline.getReasonPhrase()); - statusline = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); - assertEquals(HttpVersion.HTTP_1_1, statusline.getHttpVersion()); - assertEquals(HttpStatus.SC_OK, statusline.getStatusCode()); - assertEquals("OK", statusline.getReasonPhrase()); } public void testConstructorInvalidInput() { @@ -119,23 +115,23 @@ assertEquals(200, statusLine.getStatusCode()); assertEquals("", statusLine.getReasonPhrase()); - //this is not strictly valid, but is lienent + //this is not strictly valid, but is lenient statusLine = BasicStatusLine.parse("HTTP/1.1 200"); assertEquals(200, statusLine.getStatusCode()); assertEquals("", statusLine.getReasonPhrase()); - //this is not strictly valid, but is lienent + //this is not strictly valid, but is lenient statusLine = BasicStatusLine.parse("HTTP/1.1 200 OK"); assertEquals(200, statusLine.getStatusCode()); assertEquals("OK", statusLine.getReasonPhrase()); - //this is not strictly valid, but is lienent + //this is not strictly valid, but is lenient statusLine = BasicStatusLine.parse("\rHTTP/1.1 200 OK"); assertEquals(200, statusLine.getStatusCode()); assertEquals("OK", statusLine.getReasonPhrase()); assertEquals(HttpVersion.HTTP_1_1, statusLine.getHttpVersion()); - //this is not strictly valid, but is lienent + //this is not strictly valid, but is lenient statusLine = BasicStatusLine.parse(" HTTP/1.1 200 OK"); assertEquals(200, statusLine.getStatusCode()); assertEquals("OK", statusLine.getReasonPhrase()); Index: httpcore/module-main/src/main/java/org/apache/http/message/BasicHttpResponse.java =================================================================== --- httpcore/module-main/src/main/java/org/apache/http/message/BasicHttpResponse.java (revision 504180) +++ httpcore/module-main/src/main/java/org/apache/http/message/BasicHttpResponse.java (working copy) @@ -50,6 +50,11 @@ private StatusLine statusline = null; private HttpEntity entity = null; + /** + * Creates a new response with the given status line. + * + * @param statusline the status line + */ public BasicHttpResponse(final StatusLine statusline) { super(); if (statusline == null) { @@ -58,9 +63,18 @@ this.statusline = statusline; } - public BasicHttpResponse(final HttpVersion ver, final int code) { + /** + * Creates a new response with the given data for the status line. + * + * @param ver the HTTP version. + * @param code the HTTP status code. + * @param reason the reason phrase, or null + */ + public BasicHttpResponse(final HttpVersion ver, final int code, + final String reason) { super(); - this.statusline = new BasicStatusLine(ver, code); + // version and code will be checked in BasicStatusLine constructor + this.statusline = new BasicStatusLine(ver, code, reason); } public HttpVersion getHttpVersion() { @@ -82,21 +96,37 @@ this.statusline = statusline; } - public void setStatusLine(final HttpVersion ver, final int code) { - if (ver == null) { - throw new IllegalArgumentException("HTTP version may not be null"); - } - this.statusline = new BasicStatusLine(ver, code); + public void setStatusLine(final HttpVersion ver, final int code, + final String reason) { + // version and code will be checked in BasicStatusLine constructor + this.statusline = new BasicStatusLine(ver, code, reason); } public void setStatusCode(int code) { - if (code < 0) { - throw new IllegalArgumentException("Status line may not be null"); + if (this.statusline == null) { + throw new IllegalStateException + ("Status line has not been set."); } - HttpVersion ver = this.statusline.getHttpVersion(); - this.statusline = new BasicStatusLine(ver, code); + // code will be checked in BasicStatusLine constructor + this.statusline = new BasicStatusLine + (this.statusline.getHttpVersion(), code, null); } - + + public void setReasonPhrase(String reason) { + if (this.statusline == null) { + throw new IllegalStateException + ("Status line has not been set."); + } + // use == instead of .equals for string comparison + // don't expect any other match than if both are null + if (this.statusline.getReasonPhrase() != reason) { + this.statusline = new BasicStatusLine + (this.statusline.getHttpVersion(), + this.statusline.getStatusCode(), + reason); + } + } + public void setEntity(final HttpEntity entity) { this.entity = entity; } Index: httpcore/module-main/src/main/java/org/apache/http/message/BasicStatusLine.java =================================================================== --- httpcore/module-main/src/main/java/org/apache/http/message/BasicStatusLine.java (revision 504180) +++ httpcore/module-main/src/main/java/org/apache/http/message/BasicStatusLine.java (working copy) @@ -37,7 +37,6 @@ import org.apache.http.StatusLine; import org.apache.http.protocol.HTTP; import org.apache.http.util.CharArrayBuffer; -import org.apache.http.impl.EnglishReasonPhraseCatalog; /** @@ -83,14 +82,6 @@ this.reasonPhrase = reasonPhrase; } - /** - * Creates a new status line with the given version and status. - */ - public BasicStatusLine(final HttpVersion httpVersion, int statusCode) { - this(httpVersion, statusCode, - //@@@ TODO: reason null instead of English? - EnglishReasonPhraseCatalog.INSTANCE.getReason(statusCode, null)); - } /** * Parses the status line returned from the HTTP server. Index: httpcore/module-main/src/main/java/org/apache/http/impl/DefaultHttpResponseFactory.java =================================================================== --- httpcore/module-main/src/main/java/org/apache/http/impl/DefaultHttpResponseFactory.java (revision 504180) +++ httpcore/module-main/src/main/java/org/apache/http/impl/DefaultHttpResponseFactory.java (working copy) @@ -99,4 +99,10 @@ } return new BasicHttpResponse(statusline); } + + + // non-javadoc, see interface HttpResponseFactory + public ReasonPhraseCatalog getReasonPhraseCatalog() { + return reasonCatalog; + } } Index: httpcore/module-main/src/main/java/org/apache/http/protocol/HttpService.java =================================================================== --- httpcore/module-main/src/main/java/org/apache/http/protocol/HttpService.java (revision 504180) +++ httpcore/module-main/src/main/java/org/apache/http/protocol/HttpService.java (working copy) @@ -160,6 +160,8 @@ handleException(ex, response); } processor.process(response, context); + updateReasonPhrase(response, context); + conn.sendResponseHeader(response); conn.sendResponseEntity(response); conn.flush(); @@ -179,6 +181,23 @@ response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR); } } + + /** + * Updates the reason phrase in the status line, if it is missing. + * + * @param response the response for which to update the reason phrase + * @param context the context for the generated response + */ + protected void updateReasonPhrase(HttpResponse response, + HttpContext context) { + // generate reason phrase only if it has not been set before + if (response.getStatusLine().getReasonPhrase() == null) { + final int code = response.getStatusLine().getStatusCode(); + final String reason = this.responseFactory + .getReasonPhraseCatalog().getReason(code, context); + response.setReasonPhrase(reason); + } + } protected void doService( final HttpRequest request, Index: httpcore/module-main/src/main/java/org/apache/http/HttpResponseFactory.java =================================================================== --- httpcore/module-main/src/main/java/org/apache/http/HttpResponseFactory.java (revision 504180) +++ httpcore/module-main/src/main/java/org/apache/http/HttpResponseFactory.java (working copy) @@ -47,7 +47,16 @@ HttpResponse newHttpResponse(HttpVersion ver, int status, HttpContext context); - + HttpResponse newHttpResponse(StatusLine statusline); - + + /** + * Obtains the reason phrase catalog of this factory. + * This is the same catalog that is used by + * {@link #newHttpResponse(HttpVersion,int,HttpContext) + * newHttpResponse(version, code, context)}. + * + * @return the reason phrase catalog, never null + */ + ReasonPhraseCatalog getReasonPhraseCatalog(); } Index: httpcore/module-main/src/main/java/org/apache/http/HttpResponse.java =================================================================== --- httpcore/module-main/src/main/java/org/apache/http/HttpResponse.java (revision 504180) +++ httpcore/module-main/src/main/java/org/apache/http/HttpResponse.java (working copy) @@ -58,19 +58,41 @@ * Sets the status line that belongs to this response. * @param ver the HTTP version. * @param code the HTTP status code. + * @param reason the reason phrase, or null */ - void setStatusLine(HttpVersion ver, int code); + void setStatusLine(HttpVersion ver, int code, String reason); /** - * Convenience method that creates and sets a new status line of this - * response that is initialized with the specified status code. + * Updates the status code of this response. + * The HTTP version will be taken from the previously + * {@link #setStatusLine set} + * status line, the reason phrase is set to null. + * The reason phrase can later be updated using + * {@link #setReasonPhrase setReasonPhrase}. * - * @param code the HTTP status code. - * @see HttpStatus + * @param code the new {@link HttpStatus HTTP status} code. + * + * @throws IllegalStateException + * if no status line has previously been set */ - void setStatusCode(int code); - + void setStatusCode(int code) + throws IllegalStateException; + /** + * Updates the reason phrase of this response. + * The HTTP version and status code will be taken from the previously + * {@link #setStatusLine set} or {@link #setStatusCode updated} + * status line. + * + * @param reason the new reason phrase, or null + * + * @throws IllegalStateException + * if no status line has previously been set + */ + void setReasonPhrase(String reason) + throws IllegalStateException; + + /** * Returns the response entity of this response as set by * @link #setEntity(HttpEntity). * @return the response entity or null if there is none. Index: httpcore/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java =================================================================== --- httpcore/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java (revision 504180) +++ httpcore/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java (working copy) @@ -292,11 +292,6 @@ final NHttpServerConnection conn, final HttpException ex) { - HttpRequest request = conn.getHttpRequest(); - HttpVersion ver = request.getRequestLine().getHttpVersion(); - HttpResponse response = this.responseFactory.newHttpResponse( - ver, HttpStatus.SC_BAD_REQUEST, conn.getContext()); - int code = HttpStatus.SC_INTERNAL_SERVER_ERROR; if (ex instanceof MethodNotSupportedException) { code = HttpStatus.SC_NOT_IMPLEMENTED; @@ -306,7 +301,11 @@ code = HttpStatus.SC_BAD_REQUEST; } - response.setStatusLine(HttpVersion.HTTP_1_0, code); + HttpRequest request = conn.getHttpRequest(); + HttpVersion ver = request.getRequestLine().getHttpVersion(); + HttpResponse response = this.responseFactory.newHttpResponse( + ver, code, conn.getContext()); + byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage()); ByteArrayEntity entity = new ByteArrayEntity(msg); entity.setContentType("text/plain; charset=US-ASCII"); @@ -352,9 +351,27 @@ response = handleException(conn, ex); } + updateReasonPhrase(response, context); commitResponse(conn, response); } + /** + * Updates the reason phrase in the status line, if it is missing. + * + * @param response the response for which to update the reason phrase + * @param context the context for the generated response + */ + protected void updateReasonPhrase(HttpResponse response, + HttpContext context) { + // generate reason phrase only if it has not been set before + if (response.getStatusLine().getReasonPhrase() == null) { + final int code = response.getStatusLine().getStatusCode(); + final String reason = this.responseFactory + .getReasonPhraseCatalog().getReason(code, context); + response.setReasonPhrase(reason); + } + } + private void commitResponse( final NHttpServerConnection conn, final HttpResponse response) throws IOException, HttpException { Index: httpcore/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java =================================================================== --- httpcore/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java (revision 504180) +++ httpcore/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java (working copy) @@ -341,10 +341,6 @@ private HttpResponse handleException( final NHttpServerConnection conn, final HttpException ex) { - HttpRequest request = conn.getHttpRequest(); - HttpVersion ver = request.getRequestLine().getHttpVersion(); - HttpResponse response = this.responseFactory.newHttpResponse( - ver, HttpStatus.SC_BAD_REQUEST, conn.getContext()); int code = HttpStatus.SC_INTERNAL_SERVER_ERROR; if (ex instanceof MethodNotSupportedException) { @@ -355,7 +351,11 @@ code = HttpStatus.SC_BAD_REQUEST; } - response.setStatusLine(HttpVersion.HTTP_1_0, code); + HttpRequest request = conn.getHttpRequest(); + HttpVersion ver = request.getRequestLine().getHttpVersion(); + HttpResponse response = this.responseFactory.newHttpResponse( + ver, code, conn.getContext()); + byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage()); ByteArrayEntity entity = new ByteArrayEntity(msg); entity.setContentType("text/plain; charset=US-ASCII"); @@ -401,8 +401,26 @@ response = handleException(conn, ex); } + updateReasonPhrase(response, context); commitResponse(conn, response); } + + /** + * Updates the reason phrase in the status line, if it is missing. + * + * @param response the response for which to update the reason phrase + * @param context the context for the generated response + */ + protected void updateReasonPhrase(HttpResponse response, + HttpContext context) { + // generate reason phrase only if it has not been set before + if (response.getStatusLine().getReasonPhrase() == null) { + final int code = response.getStatusLine().getStatusCode(); + final String reason = this.responseFactory + .getReasonPhraseCatalog().getReason(code, context); + response.setReasonPhrase(reason); + } + } private void commitResponse( final NHttpServerConnection conn,