Skip to content

Commit

Permalink
built-in web server:
Browse files Browse the repository at this point in the history
support custom hosts (host mapped to localhost)
support OPTIONS methods (required for preflight request — fucking CORS)
user can rename project directory, but there is no way in WebStorm to rename project, so, we should support this case - find project by base directory name
  • Loading branch information
develar committed May 23, 2013
1 parent a4b73ce commit 11f333f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,8 @@ private boolean process(QueryStringDecoder urlDecoder, HttpRequest request, Chan
return true;
}
else if (HttpMethod.POST.getName().equals(request.getHeader("Access-Control-Request-Method"))) {
assert request.getMethod() == HttpMethod.OPTIONS;
HttpResponse response = Responses.create("text/plain");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
Responses.send(response, request, context);
LOG.assertTrue(request.getMethod() == HttpMethod.OPTIONS);
Responses.sendOptionsResponse("POST, OPTIONS", request, context);
return true;
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void messageReceived(ChannelHandlerContext context, MessageEvent event) t
BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
icon.paintIcon(null, image.getGraphics(), 0, 0);
byte[] icoBytes = Sanselan.writeImageToBytes(image, ImageFormat.IMAGE_FORMAT_ICO, null);
Responses.send(FileResponses.createResponse(urlDecoder.getPath()), icoBytes, request, context);
Responses.send(icoBytes, FileResponses.createResponse(urlDecoder.getPath()), request, context);
return;
}
}
Expand All @@ -62,7 +62,7 @@ else if (connectedHandler.isSupported(request)) {
connectedHandler.process(urlDecoder, request, context);
return;
}
Responses.sendError(request, context, NOT_FOUND);
Responses.sendStatus(request, context, NOT_FOUND);
}

@Override
Expand Down
15 changes: 7 additions & 8 deletions platform/platform-impl/src/org/jetbrains/io/FileResponses.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
package org.jetbrains.io;

import org.jboss.netty.channel.*;
import org.jboss.netty.handler.codec.http.*;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.ssl.SslHandler;
import org.jboss.netty.handler.stream.ChunkedFile;

Expand All @@ -28,7 +31,6 @@
import java.util.Date;

import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive;
import static org.jboss.netty.handler.codec.http.HttpHeaders.setContentLength;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.NOT_MODIFIED;
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
Expand Down Expand Up @@ -74,12 +76,9 @@ public static void sendFile(HttpRequest request, ChannelHandlerContext context,
try {
long fileLength = raf.length();
HttpResponse response = createResponse(file.getPath());
addDate(response);
addAllowAnyOrigin(response);
addCommonHeaders(response);
response.setHeader(LAST_MODIFIED, Responses.DATE_FORMAT.get().format(new Date(file.lastModified())));
if (isKeepAlive(request)) {
response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
}
boolean keepAlive = addKeepAliveIfNeed(response, request);
if (request.getMethod() != HttpMethod.HEAD) {
setContentLength(response, fileLength);
}
Expand All @@ -105,7 +104,7 @@ public void operationComplete(ChannelFuture future) {
}
}

if (!isKeepAlive(request)) {
if (!keepAlive) {
future.addListener(ChannelFutureListener.CLOSE);
}

Expand Down
63 changes: 39 additions & 24 deletions platform/platform-impl/src/org/jetbrains/io/Responses.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.jboss.netty.handler.codec.http.*;
import org.jboss.netty.util.CharsetUtil;

import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
Expand Down Expand Up @@ -55,9 +56,7 @@ protected DateFormat initialValue() {
private static String SERVER_HEADER_VALUE;

public static void addAllowAnyOrigin(HttpResponse response) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
}

public static void addDate(HttpResponse response) {
Expand Down Expand Up @@ -88,10 +87,25 @@ public static void send(String contentType, CharSequence content, HttpRequest re

public static void send(HttpResponse response, HttpRequest request, ChannelHandlerContext context) {
ChannelBuffer content = response.getContent();
if (content != ChannelBuffers.EMPTY_BUFFER) {
setContentLength(response, content.readableBytes());
setContentLength(response, content == ChannelBuffers.EMPTY_BUFFER ? 0 : content.readableBytes());

boolean keepAlive = addKeepAliveIfNeed(response, request);
addCommonHeaders(response);
send(response, context, !keepAlive);
}

public static boolean addKeepAliveIfNeed(HttpResponse response, HttpRequest request) {
if (isKeepAlive(request)) {
response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
return true;
}
send(response, context, !isKeepAlive(request));
return false;
}

public static void addCommonHeaders(HttpResponse response) {
addServer(response);
addDate(response);
addAllowAnyOrigin(response);
}

public static HttpResponse create(String contentType) {
Expand All @@ -101,21 +115,17 @@ public static HttpResponse create(String contentType) {
}

public static void send(CharSequence content, HttpRequest request, ChannelHandlerContext context) {
send(new DefaultHttpResponse(HTTP_1_1, OK), ChannelBuffers.copiedBuffer(content, CharsetUtil.US_ASCII), request, context);
send(content, CharsetUtil.US_ASCII, request, context);
}

public static void send(HttpResponse response, byte[] bytes, HttpRequest request, ChannelHandlerContext context) {
send(response, ChannelBuffers.wrappedBuffer(bytes), request, context);
public static void send(CharSequence content, Charset charset, HttpRequest request, ChannelHandlerContext context) {
DefaultHttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
response.setContent(ChannelBuffers.copiedBuffer(content, charset));
send(response, request, context);
}

public static void send(HttpResponse response, ChannelBuffer content, HttpRequest request, ChannelHandlerContext context) {
if (isKeepAlive(request)) {
response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
}
response.setContent(content);
addServer(response);
addDate(response);
addAllowAnyOrigin(response);
public static void send(byte[] bytes, HttpResponse response, HttpRequest request, ChannelHandlerContext context) {
response.setContent(ChannelBuffers.wrappedBuffer(bytes));
send(response, request, context);
}

Expand All @@ -134,21 +144,26 @@ public static void send(HttpResponse response, ChannelHandlerContext context, bo
}
}

public static void sendError(HttpRequest request, ChannelHandlerContext context, HttpResponseStatus responseStatus) {
sendError(request, context, new DefaultHttpResponse(HTTP_1_1, responseStatus));
public static void sendStatus(HttpRequest request, ChannelHandlerContext context, HttpResponseStatus responseStatus) {
sendStatus(new DefaultHttpResponse(HTTP_1_1, responseStatus), request, context);
}

public static void sendError(HttpRequest request, ChannelHandlerContext context, HttpResponse response) {
public static void sendStatus(HttpResponse response, HttpRequest request, ChannelHandlerContext context) {
response.setHeader(CONTENT_TYPE, "text/html");
addServer(response);
addDate(response);

String message = response.getStatus().toString();
if (request.getMethod() != HttpMethod.HEAD) {
String message = response.getStatus().toString();
response.setContent(ChannelBuffers.copiedBuffer("<!doctype html><title>" + message + "</title>" +
"<h1 style=\"text-align: center\">" + message + "</h1><hr/><p style=\"text-align: center\">" + SERVER_HEADER_VALUE + "</p>",
CharsetUtil.US_ASCII));
}
send(response, request, context);
}

public static void sendOptionsResponse(String allowHeaders, HttpRequest request, ChannelHandlerContext context) {
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
response.setHeader(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
response.setHeader(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_METHODS, allowHeaders);
response.setHeader(HttpHeaders.Names.ALLOW, allowHeaders);
send(response, request, context);
}
}

0 comments on commit 11f333f

Please sign in to comment.