Issue 62: always set Content-Length

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1424 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-06-11 23:20:37 +00:00
parent cd1c3ae900
commit e773803ee2
4 changed files with 189 additions and 185 deletions

View File

@ -34,6 +34,7 @@ import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpFutureCommand; import org.jclouds.http.HttpFutureCommand;
import org.jclouds.http.HttpFutureCommandClient; import org.jclouds.http.HttpFutureCommandClient;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
@ -49,101 +50,95 @@ import com.google.inject.Inject;
*/ */
public class JavaUrlHttpFutureCommandClient extends BaseHttpFutureCommandClient { public class JavaUrlHttpFutureCommandClient extends BaseHttpFutureCommandClient {
@Inject @Inject
public JavaUrlHttpFutureCommandClient(URL target) public JavaUrlHttpFutureCommandClient(URL target) throws MalformedURLException {
throws MalformedURLException { super(target);
super(target); }
}
public void submit(HttpFutureCommand<?> command) { public void submit(HttpFutureCommand<?> command) {
HttpRequest request = command.getRequest(); HttpRequest request = command.getRequest();
HttpURLConnection connection = null; HttpURLConnection connection = null;
try { try {
HttpResponse response = null; HttpResponse response = null;
for (;;) { for (;;) {
for (HttpRequestFilter filter : requestFilters) { for (HttpRequestFilter filter : requestFilters) {
filter.filter(request); filter.filter(request);
} }
logger.trace("%1$s - converting request %2$s", target, request); logger.trace("%1$s - converting request %2$s", target, request);
connection = openJavaConnection(request); connection = openJavaConnection(request);
logger logger.trace("%1$s - submitting request %2$s", target, connection);
.trace("%1$s - submitting request %2$s", target, response = getResponse(connection);
connection); logger.trace("%1$s - received response %2$s", target, response);
response = getResponse(connection); if (response.getStatusCode() >= 500 && httpRetryHandler.retryRequest(command, response))
logger.trace("%1$s - received response %2$s", target, response); continue;
if (response.getStatusCode() >= 500 && httpRetryHandler.retryRequest(command, response)) break;
continue; }
break; handleResponse(command, response);
} } catch (Exception e) {
handleResponse(command, response); command.setException(e);
} catch (Exception e) { } finally {
command.setException(e); // DO NOT disconnect, as it will also close the unconsumed
} finally { // outputStream from above.
// DO NOT disconnect, as it will also close the unconsumed if (request.getMethod().equals("HEAD"))
// outputStream from above. connection.disconnect();
if (request.getMethod().equals("HEAD")) }
connection.disconnect(); }
}
}
protected HttpResponse getResponse(HttpURLConnection connection) protected HttpResponse getResponse(HttpURLConnection connection) throws IOException {
throws IOException { HttpResponse response = new HttpResponse();
HttpResponse response = new HttpResponse(); InputStream in;
InputStream in; try {
try { in = connection.getInputStream();
in = connection.getInputStream(); } catch (IOException e) {
} catch (IOException e) { in = connection.getErrorStream();
in = connection.getErrorStream(); }
} if (in != null) {
if (in != null) { response.setContent(in);
response.setContent(in); }
} response.setStatusCode(connection.getResponseCode());
response.setStatusCode(connection.getResponseCode()); for (String header : connection.getHeaderFields().keySet()) {
for (String header : connection.getHeaderFields().keySet()) { response.getHeaders().putAll(header, connection.getHeaderFields().get(header));
response.getHeaders().putAll(header, }
connection.getHeaderFields().get(header));
}
response.setMessage(connection.getResponseMessage()); response.setMessage(connection.getResponseMessage());
return response; return response;
} }
protected HttpURLConnection openJavaConnection(HttpRequest request) protected HttpURLConnection openJavaConnection(HttpRequest request) throws IOException {
throws IOException { URL url = new URL(target, request.getUri());
URL url = new URL(target, request.getUri()); HttpURLConnection connection = (HttpURLConnection) url.openConnection();
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true);
connection.setDoOutput(true); connection.setAllowUserInteraction(false);
connection.setAllowUserInteraction(false); connection.setInstanceFollowRedirects(true);
connection.setInstanceFollowRedirects(true); connection.setRequestMethod(request.getMethod());
connection.setRequestMethod(request.getMethod()); for (String header : request.getHeaders().keySet()) {
for (String header : request.getHeaders().keySet()) { for (String value : request.getHeaders().get(header))
for (String value : request.getHeaders().get(header)) connection.setRequestProperty(header, value);
connection.setRequestProperty(header, value); }
} if (request.getPayload() != null) {
if (request.getPayload() != null) { OutputStream out = connection.getOutputStream();
OutputStream out = connection.getOutputStream(); try {
try { if (request.getPayload() instanceof String) {
if (request.getPayload() instanceof String) { OutputStreamWriter writer = new OutputStreamWriter(out);
OutputStreamWriter writer = new OutputStreamWriter(out); writer.write((String) request.getPayload());
writer.write((String) request.getPayload()); writer.close();
writer.close(); } else if (request.getPayload() instanceof InputStream) {
} else if (request.getPayload() instanceof InputStream) { IOUtils.copy((InputStream) request.getPayload(), out);
IOUtils.copy((InputStream) request.getPayload(), out); } else if (request.getPayload() instanceof File) {
} else if (request.getPayload() instanceof File) { IOUtils.copy(new FileInputStream((File) request.getPayload()), out);
IOUtils.copy(new FileInputStream((File) request } else if (request.getPayload() instanceof byte[]) {
.getPayload()), out); IOUtils.write((byte[]) request.getPayload(), out);
} else if (request.getPayload() instanceof byte[]) { } else {
IOUtils.write((byte[]) request.getPayload(), out); throw new UnsupportedOperationException("Content not supported "
} else { + request.getPayload().getClass());
throw new UnsupportedOperationException( }
"Content not supported " } finally {
+ request.getPayload().getClass()); IOUtils.closeQuietly(out);
} }
} finally {
IOUtils.closeQuietly(out);
}
} } else {
return connection; connection.setRequestProperty(HttpConstants.CONTENT_LENGTH, "0");
} }
return connection;
}
} }

View File

@ -55,101 +55,108 @@ import com.google.inject.TypeLiteral;
import com.google.inject.name.Names; import com.google.inject.name.Names;
public abstract class BaseJettyTest { public abstract class BaseJettyTest {
protected static final String XML = "<foo><bar>whoppers</bar></foo>"; protected static final String XML = "<foo><bar>whoppers</bar></foo>";
protected Server server = null; protected Server server = null;
protected CommandFactory factory; protected CommandFactory factory;
protected HttpFutureCommandClient client; protected HttpFutureCommandClient client;
protected Injector injector; protected Injector injector;
private Closer closer; private Closer closer;
private AtomicInteger cycle = new AtomicInteger(0); private AtomicInteger cycle = new AtomicInteger(0);
@BeforeTest @BeforeTest
@Parameters( { "test-jetty-port" }) @Parameters( { "test-jetty-port" })
public void setUpJetty(@Optional("8123") final int testPort) public void setUpJetty(@Optional("8123") final int testPort) throws Exception {
throws Exception { Handler handler = new AbstractHandler() {
Handler handler = new AbstractHandler() {
public void handle(String target, HttpServletRequest request, public void handle(String target, HttpServletRequest request,
HttpServletResponse response, int dispatch) HttpServletResponse response, int dispatch) throws IOException, ServletException {
throws IOException, ServletException { failIfNoContentLength(request, response);
if (request.getHeader("test") != null) { if (request.getHeader("test") != null) {
response.setContentType("text/plain"); response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("test"); response.getWriter().println("test");
} else { } else {
if (failOnRequest(request, response)) if (failOnRequest(request, response))
return; return;
response.setContentType("text/xml"); response.setContentType("text/xml");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println(XML); response.getWriter().println(XML);
} }
((Request) request).setHandled(true); ((Request) request).setHandled(true);
} }
}; };
server = new Server(testPort); server = new Server(testPort);
server.setHandler(handler); server.setHandler(handler);
server.start(); server.start();
final Properties properties = new Properties(); final Properties properties = new Properties();
properties.put(HttpConstants.PROPERTY_HTTP_ADDRESS, "localhost"); properties.put(HttpConstants.PROPERTY_HTTP_ADDRESS, "localhost");
properties.put(HttpConstants.PROPERTY_HTTP_PORT, testPort + ""); properties.put(HttpConstants.PROPERTY_HTTP_PORT, testPort + "");
properties.put(HttpConstants.PROPERTY_HTTP_SECURE, "false"); properties.put(HttpConstants.PROPERTY_HTTP_SECURE, "false");
addConnectionProperties(properties); addConnectionProperties(properties);
final List<HttpRequestFilter> filters = new ArrayList<HttpRequestFilter>( final List<HttpRequestFilter> filters = new ArrayList<HttpRequestFilter>(1);
1); filters.add(new HttpRequestFilter() {
filters.add(new HttpRequestFilter() { public void filter(HttpRequest request) throws HttpException {
public void filter(HttpRequest request) throws HttpException { if (request.getHeaders().containsKey("filterme")) {
if (request.getHeaders().containsKey("filterme")) { request.getHeaders().put("test", "test");
request.getHeaders().put("test", "test"); }
} }
} });
}); injector = Guice.createInjector(new AbstractModule() {
injector = Guice.createInjector(new AbstractModule() { @Override
@Override protected void configure() {
protected void configure() { Names.bindProperties(binder(), properties);
Names.bindProperties(binder(), properties); }
} }, new JDKLoggingModule(), new HttpCommandsModule(), createClientModule(),
}, new JDKLoggingModule(), new HttpCommandsModule(), new AbstractModule() {
createClientModule(), new AbstractModule() { @Override
@Override protected void configure() {
protected void configure() { bind(new TypeLiteral<List<HttpRequestFilter>>() {
bind(new TypeLiteral<List<HttpRequestFilter>>() { }).toInstance(filters);
}).toInstance(filters); }
} });
}); factory = injector.getInstance(Key.get(CommandFactory.class));
factory = injector.getInstance(Key.get(CommandFactory.class)); client = injector.getInstance(HttpFutureCommandClient.class);
client = injector.getInstance(HttpFutureCommandClient.class); closer = injector.getInstance(Closer.class);
closer = injector.getInstance(Closer.class); assert client != null;
assert client != null; }
}
@AfterTest
public void tearDownJetty() throws Exception {
closer.close();
server.stop();
}
protected abstract void addConnectionProperties(Properties props); @AfterTest
public void tearDownJetty() throws Exception {
closer.close();
server.stop();
}
protected abstract void addConnectionProperties(Properties props);
protected abstract Module createClientModule();
/**
* Fails every 10 requests.
*
* @param request
* @param response
* @return
* @throws IOException
*/
protected boolean failOnRequest(HttpServletRequest request, HttpServletResponse response)
throws IOException {
if (cycle.incrementAndGet() % 10 == 0) {
response.sendError(500);
((Request) request).setHandled(true);
return true;
}
return false;
}
protected boolean failIfNoContentLength(HttpServletRequest request, HttpServletResponse response)
throws IOException {
if (request.getHeader(HttpConstants.CONTENT_LENGTH) == null) {
response.sendError(500);
((Request) request).setHandled(true);
return true;
}
return false;
}
protected abstract Module createClientModule();
/**
* Fails every 10 requests.
*
* @param request
* @param response
* @return
* @throws IOException
*/
protected boolean failOnRequest(HttpServletRequest request,
HttpServletResponse response) throws IOException {
if (cycle.incrementAndGet() % 10 == 0) {
response.sendError(500);
((Request) request).setHandled(true);
return true;
}
return false;
}
} }

View File

@ -179,6 +179,8 @@ public class URLFetchServiceClient extends BaseHttpFutureCommandClient {
if (request.getPayload() != null) { if (request.getPayload() != null) {
changeRequestContentToBytes(request); changeRequestContentToBytes(request);
gaeRequest.setPayload((byte[]) request.getPayload()); gaeRequest.setPayload((byte[]) request.getPayload());
} else {
gaeRequest.addHeader(new HTTPHeader(HttpConstants.CONTENT_LENGTH, "0"));
} }
return gaeRequest; return gaeRequest;
} }

View File

@ -126,7 +126,7 @@ public class URLFetchServiceClientTest {
HttpRequest request = new HttpRequest("GET", "foo"); HttpRequest request = new HttpRequest("GET", "foo");
HTTPRequest gaeRequest = client.convert(request); HTTPRequest gaeRequest = client.convert(request);
assert gaeRequest.getPayload() == null; assert gaeRequest.getPayload() == null;
assertEquals(gaeRequest.getHeaders().size(), 0); assertEquals(gaeRequest.getHeaders().size(), 1);//content length
} }
@Test @Test