Skip to content

Commit 11f333f

Browse files
committed
built-in web server:
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
1 parent a4b73ce commit 11f333f

4 files changed

Lines changed: 50 additions & 39 deletions

File tree

platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,8 @@ private boolean process(QueryStringDecoder urlDecoder, HttpRequest request, Chan
128128
return true;
129129
}
130130
else if (HttpMethod.POST.getName().equals(request.getHeader("Access-Control-Request-Method"))) {
131-
assert request.getMethod() == HttpMethod.OPTIONS;
132-
HttpResponse response = Responses.create("text/plain");
133-
response.setHeader("Access-Control-Allow-Origin", "*");
134-
response.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
135-
Responses.send(response, request, context);
131+
LOG.assertTrue(request.getMethod() == HttpMethod.OPTIONS);
132+
Responses.sendOptionsResponse("POST, OPTIONS", request, context);
136133
return true;
137134
}
138135
return false;

platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public void messageReceived(ChannelHandlerContext context, MessageEvent event) t
3535
BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
3636
icon.paintIcon(null, image.getGraphics(), 0, 0);
3737
byte[] icoBytes = Sanselan.writeImageToBytes(image, ImageFormat.IMAGE_FORMAT_ICO, null);
38-
Responses.send(FileResponses.createResponse(urlDecoder.getPath()), icoBytes, request, context);
38+
Responses.send(icoBytes, FileResponses.createResponse(urlDecoder.getPath()), request, context);
3939
return;
4040
}
4141
}
@@ -62,7 +62,7 @@ else if (connectedHandler.isSupported(request)) {
6262
connectedHandler.process(urlDecoder, request, context);
6363
return;
6464
}
65-
Responses.sendError(request, context, NOT_FOUND);
65+
Responses.sendStatus(request, context, NOT_FOUND);
6666
}
6767

6868
@Override

platform/platform-impl/src/org/jetbrains/io/FileResponses.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
package org.jetbrains.io;
1717

1818
import org.jboss.netty.channel.*;
19-
import org.jboss.netty.handler.codec.http.*;
19+
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
20+
import org.jboss.netty.handler.codec.http.HttpMethod;
21+
import org.jboss.netty.handler.codec.http.HttpRequest;
22+
import org.jboss.netty.handler.codec.http.HttpResponse;
2023
import org.jboss.netty.handler.ssl.SslHandler;
2124
import org.jboss.netty.handler.stream.ChunkedFile;
2225

@@ -28,7 +31,6 @@
2831
import java.util.Date;
2932

3033
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
31-
import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive;
3234
import static org.jboss.netty.handler.codec.http.HttpHeaders.setContentLength;
3335
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.NOT_MODIFIED;
3436
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
@@ -74,12 +76,9 @@ public static void sendFile(HttpRequest request, ChannelHandlerContext context,
7476
try {
7577
long fileLength = raf.length();
7678
HttpResponse response = createResponse(file.getPath());
77-
addDate(response);
78-
addAllowAnyOrigin(response);
79+
addCommonHeaders(response);
7980
response.setHeader(LAST_MODIFIED, Responses.DATE_FORMAT.get().format(new Date(file.lastModified())));
80-
if (isKeepAlive(request)) {
81-
response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
82-
}
81+
boolean keepAlive = addKeepAliveIfNeed(response, request);
8382
if (request.getMethod() != HttpMethod.HEAD) {
8483
setContentLength(response, fileLength);
8584
}
@@ -105,7 +104,7 @@ public void operationComplete(ChannelFuture future) {
105104
}
106105
}
107106

108-
if (!isKeepAlive(request)) {
107+
if (!keepAlive) {
109108
future.addListener(ChannelFutureListener.CLOSE);
110109
}
111110

platform/platform-impl/src/org/jetbrains/io/Responses.java

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.jboss.netty.handler.codec.http.*;
2727
import org.jboss.netty.util.CharsetUtil;
2828

29+
import java.nio.charset.Charset;
2930
import java.text.DateFormat;
3031
import java.text.SimpleDateFormat;
3132
import java.util.Calendar;
@@ -55,9 +56,7 @@ protected DateFormat initialValue() {
5556
private static String SERVER_HEADER_VALUE;
5657

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

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

8988
public static void send(HttpResponse response, HttpRequest request, ChannelHandlerContext context) {
9089
ChannelBuffer content = response.getContent();
91-
if (content != ChannelBuffers.EMPTY_BUFFER) {
92-
setContentLength(response, content.readableBytes());
90+
setContentLength(response, content == ChannelBuffers.EMPTY_BUFFER ? 0 : content.readableBytes());
91+
92+
boolean keepAlive = addKeepAliveIfNeed(response, request);
93+
addCommonHeaders(response);
94+
send(response, context, !keepAlive);
95+
}
96+
97+
public static boolean addKeepAliveIfNeed(HttpResponse response, HttpRequest request) {
98+
if (isKeepAlive(request)) {
99+
response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
100+
return true;
93101
}
94-
send(response, context, !isKeepAlive(request));
102+
return false;
103+
}
104+
105+
public static void addCommonHeaders(HttpResponse response) {
106+
addServer(response);
107+
addDate(response);
108+
addAllowAnyOrigin(response);
95109
}
96110

97111
public static HttpResponse create(String contentType) {
@@ -101,21 +115,17 @@ public static HttpResponse create(String contentType) {
101115
}
102116

103117
public static void send(CharSequence content, HttpRequest request, ChannelHandlerContext context) {
104-
send(new DefaultHttpResponse(HTTP_1_1, OK), ChannelBuffers.copiedBuffer(content, CharsetUtil.US_ASCII), request, context);
118+
send(content, CharsetUtil.US_ASCII, request, context);
105119
}
106120

107-
public static void send(HttpResponse response, byte[] bytes, HttpRequest request, ChannelHandlerContext context) {
108-
send(response, ChannelBuffers.wrappedBuffer(bytes), request, context);
121+
public static void send(CharSequence content, Charset charset, HttpRequest request, ChannelHandlerContext context) {
122+
DefaultHttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
123+
response.setContent(ChannelBuffers.copiedBuffer(content, charset));
124+
send(response, request, context);
109125
}
110126

111-
public static void send(HttpResponse response, ChannelBuffer content, HttpRequest request, ChannelHandlerContext context) {
112-
if (isKeepAlive(request)) {
113-
response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
114-
}
115-
response.setContent(content);
116-
addServer(response);
117-
addDate(response);
118-
addAllowAnyOrigin(response);
127+
public static void send(byte[] bytes, HttpResponse response, HttpRequest request, ChannelHandlerContext context) {
128+
response.setContent(ChannelBuffers.wrappedBuffer(bytes));
119129
send(response, request, context);
120130
}
121131

@@ -134,21 +144,26 @@ public static void send(HttpResponse response, ChannelHandlerContext context, bo
134144
}
135145
}
136146

137-
public static void sendError(HttpRequest request, ChannelHandlerContext context, HttpResponseStatus responseStatus) {
138-
sendError(request, context, new DefaultHttpResponse(HTTP_1_1, responseStatus));
147+
public static void sendStatus(HttpRequest request, ChannelHandlerContext context, HttpResponseStatus responseStatus) {
148+
sendStatus(new DefaultHttpResponse(HTTP_1_1, responseStatus), request, context);
139149
}
140150

141-
public static void sendError(HttpRequest request, ChannelHandlerContext context, HttpResponse response) {
151+
public static void sendStatus(HttpResponse response, HttpRequest request, ChannelHandlerContext context) {
142152
response.setHeader(CONTENT_TYPE, "text/html");
143-
addServer(response);
144-
addDate(response);
145-
146-
String message = response.getStatus().toString();
147153
if (request.getMethod() != HttpMethod.HEAD) {
154+
String message = response.getStatus().toString();
148155
response.setContent(ChannelBuffers.copiedBuffer("<!doctype html><title>" + message + "</title>" +
149156
"<h1 style=\"text-align: center\">" + message + "</h1><hr/><p style=\"text-align: center\">" + SERVER_HEADER_VALUE + "</p>",
150157
CharsetUtil.US_ASCII));
151158
}
152159
send(response, request, context);
153160
}
161+
162+
public static void sendOptionsResponse(String allowHeaders, HttpRequest request, ChannelHandlerContext context) {
163+
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
164+
response.setHeader(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
165+
response.setHeader(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_METHODS, allowHeaders);
166+
response.setHeader(HttpHeaders.Names.ALLOW, allowHeaders);
167+
send(response, request, context);
168+
}
154169
}

0 commit comments

Comments
 (0)