Support Cross-Origin resource in http/rest module, closes #218.

This commit is contained in:
kimchy 2010-07-19 15:06:13 +03:00
parent e48b1d98db
commit 5f0470d68b
7 changed files with 37 additions and 11 deletions

View File

@ -22,7 +22,7 @@ package org.elasticsearch.http;
import org.elasticsearch.rest.RestResponse;
/**
* @author kimchy (Shay Banon)
* @author kimchy (shay.banon)
*/
public interface HttpResponse extends RestResponse {

View File

@ -27,11 +27,14 @@ import org.elasticsearch.common.path.PathTrie;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.StringRestResponse;
import org.elasticsearch.rest.XContentThrowableRestResponse;
import org.elasticsearch.threadpool.ThreadPool;
import java.io.IOException;
import static org.elasticsearch.rest.RestResponse.Status.*;
/**
* @author kimchy (shay.banon)
*/
@ -103,7 +106,16 @@ public class HttpServer extends AbstractLifecycleComponent<HttpServer> {
void internalDispatchRequest(final HttpRequest request, final HttpChannel channel) {
final HttpServerHandler httpHandler = getHandler(request);
if (httpHandler == null) {
restController.dispatchRequest(request, channel);
// if nothing was dispatched by the rest request, send either error or default handling per method
if (!restController.dispatchRequest(request, channel)) {
if (request.method() == RestRequest.Method.OPTIONS) {
// when we have OPTIONS request, simply send OK by default (with the Access Control Origin header which gest automatically added)
StringRestResponse response = new StringRestResponse(OK);
channel.sendResponse(response);
} else {
channel.sendResponse(new StringRestResponse(BAD_REQUEST, "No handler found for uri [" + request.uri() + "] and method [" + request.method() + "]"));
}
}
} else {
if (httpHandler.spawn()) {
threadPool.execute(new Runnable() {

View File

@ -34,7 +34,7 @@ import java.io.IOException;
import java.util.Set;
/**
* @author kimchy (Shay Banon)
* @author kimchy (shay.banon)
*/
public class NettyHttpChannel implements HttpChannel {
private final Channel channel;
@ -64,6 +64,14 @@ public class NettyHttpChannel implements HttpChannel {
} else {
resp = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status);
}
// add support for cross origin
resp.addHeader("Access-Control-Allow-Origin", "*");
if (request.getMethod() == HttpMethod.OPTIONS) {
// also add more access control parameters
resp.addHeader("Access-Control-Max-Age", 1728000);
resp.addHeader("Access-Control-Allow-Methods", "PUT, DELETE");
}
// Convert the response content to a ChannelBuffer.
ChannelBuffer buf;
try {

View File

@ -28,8 +28,6 @@ import org.elasticsearch.common.settings.Settings;
import java.io.IOException;
import static org.elasticsearch.rest.RestResponse.Status.*;
/**
* @author kimchy (shay.banon)
*/
@ -80,11 +78,10 @@ public class RestController extends AbstractLifecycleComponent<RestController> {
}
}
public void dispatchRequest(final RestRequest request, final RestChannel channel) {
public boolean dispatchRequest(final RestRequest request, final RestChannel channel) {
final RestHandler handler = getHandler(request);
if (handler == null) {
channel.sendResponse(new StringRestResponse(BAD_REQUEST, "No handler found for uri [" + request.uri() + "] and method [" + request.method() + "]"));
return;
return false;
}
try {
handler.handleRequest(request, channel);
@ -95,6 +92,7 @@ public class RestController extends AbstractLifecycleComponent<RestController> {
logger.error("Failed to send failure response for uri [" + request.uri() + "]", e1);
}
}
return true;
}
private RestHandler getHandler(RestRequest request) {

View File

@ -23,7 +23,7 @@ import org.apache.lucene.util.UnicodeUtil;
import org.elasticsearch.common.thread.ThreadLocals;
/**
* @author kimchy (Shay Banon)
* @author kimchy (shay.banon)
*/
public class StringRestResponse extends Utf8RestResponse {

View File

@ -26,7 +26,7 @@ import org.apache.lucene.util.UnicodeUtil;
*
* <p>Note, this class assumes that the utf8 result is not thread safe.
*
* @author kimchy (Shay Banon)
* @author kimchy (shay.banon)
*/
public class Utf8RestResponse extends AbstractRestResponse implements RestResponse {

View File

@ -24,6 +24,9 @@ import org.elasticsearch.common.netty.channel.MessageEvent;
import org.elasticsearch.common.netty.channel.SimpleChannelUpstreamHandler;
import org.elasticsearch.memcached.MemcachedRestRequest;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.StringRestResponse;
import static org.elasticsearch.rest.RestResponse.Status.*;
/**
* @author kimchy (shay.banon)
@ -38,7 +41,12 @@ public class MemcachedDispatcher extends SimpleChannelUpstreamHandler {
@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
MemcachedRestRequest request = (MemcachedRestRequest) e.getMessage();
restController.dispatchRequest(request, new MemcachedRestChannel(ctx.getChannel(), request));
MemcachedRestChannel channel = new MemcachedRestChannel(ctx.getChannel(), request);
if (!restController.dispatchRequest(request, channel)) {
channel.sendResponse(new StringRestResponse(BAD_REQUEST, "No handler found for uri [" + request.uri() + "] and method [" + request.method() + "]"));
}
super.messageReceived(ctx, e);
}
}