JETTY-1410 HTTP client handles CONTINUE 100 response correctly

This commit is contained in:
Michael Gorovoy 2011-08-22 09:58:13 -04:00 committed by Greg Wilkins
parent 96d46df7da
commit 07b8f08a37
4 changed files with 167 additions and 9 deletions

View File

@ -5,6 +5,7 @@ jetty-7.5.0.RC1 - 19 August 2011
+ 335001 Eliminate expected exceptions from log when running in JBoss
+ 355103 Make allowCredentials default to true in CrossOriginFilter
+ 355162 Allow creating an empty resource collection
+ JETTY-1410 HTTP client handles CONTINUE 100 response correctly
+ JETTY-1414 HashLoginService doesn't refresh realm if specified config filename is not an absolute platform specific value
jetty-7.5.0.RC0 - 15 August 2011

View File

@ -70,7 +70,7 @@ public class HttpConnection extends AbstractConnection implements Dumpable
HttpConnection(Buffers requestBuffers, Buffers responseBuffers, EndPoint endp)
{
super(endp);
_generator = new HttpGenerator(requestBuffers,endp);
_parser = new HttpParser(responseBuffers,endp,new Handler());
}
@ -575,10 +575,19 @@ public class HttpConnection extends AbstractConnection implements Dumpable
HttpExchange exchange = _exchange;
if (exchange!=null)
{
// handle special case for CONNECT 200 responses
if (status==HttpStatus.OK_200 && HttpMethods.CONNECT.equalsIgnoreCase(exchange.getMethod()))
_parser.setHeadResponse(true);
switch(status)
{
case HttpStatus.CONTINUE_100:
// handle special case for CONTINUE 100 responses
return;
case HttpStatus.OK_200:
// handle special case for CONNECT 200 responses
if (HttpMethods.CONNECT.equalsIgnoreCase(exchange.getMethod()))
_parser.setHeadResponse(true);
break;
}
_http11 = HttpVersions.HTTP_1_1_BUFFER.equals(version);
_status=status;
exchange.getEventListener().onResponseStatus(version,status,reason);

View File

@ -0,0 +1,140 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/* ------------------------------------------------------------ */
public class Http100ContinueTest
{
private static final String CONTENT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "
+ "Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "
+ "habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "
+ "Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam "
+ "at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate "
+ "velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. "
+ "Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum "
+ "eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa "
+ "sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam "
+ "consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. "
+ "Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "
+ "et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
private Server _server;
private TestHandler _handler;
private int _port;
@Before
public void init() throws Exception
{
File docRoot = new File("target/test-output/docroot/");
if (!docRoot.exists())
assertTrue(docRoot.mkdirs());
docRoot.deleteOnExit();
_server = new Server();
Connector connector = new SelectChannelConnector();
_server.addConnector(connector);
_handler = new TestHandler();
_server.setHandler(_handler);
_server.start();
_port = connector.getLocalPort();
}
@After
public void destroy() throws Exception
{
_server.stop();
_server.join();
}
@Test
public void testSelectConnector() throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
httpClient.start();
try
{
String requestUrl = "http://localhost:" + _port + "/header";
ContentExchange exchange = new ContentExchange();
exchange.setURL(requestUrl);
exchange.setMethod(HttpMethods.GET);
exchange.addRequestHeader("User-Agent","Jetty-Client/7.0");
exchange.addRequestHeader("Expect","100-continue"); //server to send CONTINUE 100
httpClient.send(exchange);
int state = exchange.waitForDone();
assertEquals(HttpExchange.STATUS_COMPLETED, state);
int responseStatus = exchange.getResponseStatus();
assertEquals(HttpStatus.OK_200,responseStatus);
String content = exchange.getResponseContent();
assertEquals(Http100ContinueTest.CONTENT,content);
}
finally
{
httpClient.stop();
}
}
private static class TestHandler extends AbstractHandler
{
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
if (baseRequest.isHandled())
return;
// force 100 Continue response to be sent
request.getInputStream();
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().print(CONTENT);
baseRequest.setHandled(true);
}
}
}

View File

@ -557,10 +557,18 @@ public class HttpParser implements Parser
break;
case HttpTokens.NO_CONTENT:
_state=STATE_END;
returnBuffers();
_handler.headerComplete();
_handler.messageComplete(_contentPosition);
if (_responseStatus != 100) // continue
{
_state=STATE_END;
returnBuffers();
_handler.headerComplete();
_handler.messageComplete(_contentPosition);
}
else
{
reset();
}
break;
default: