mirror of https://github.com/apache/jclouds.git
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:
parent
cd1c3ae900
commit
e773803ee2
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue