Skip to content

Commit fb70dd7

Browse files
committed
Abstracted the http server logic to allow for using a custom http server implementation and finished the custom http implementation. Added a JettyHTTPSocketServer as a backup option, but it doesn't support websockets.
1 parent 9cd7a0c commit fb70dd7

33 files changed

+973
-1077
lines changed

src/main/java/org/javawebstack/httpserver/Exchange.java

Lines changed: 39 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
package org.javawebstack.httpserver;
22

33
import org.javawebstack.abstractdata.*;
4-
import org.javawebstack.httpserver.helper.HttpMethod;
5-
import org.javawebstack.httpserver.helper.MimeType;
4+
import org.javawebstack.httpserver.adapter.IHTTPSocket;
5+
import org.javawebstack.httpserver.util.MimeType;
66
import org.javawebstack.validator.ValidationContext;
77
import org.javawebstack.validator.ValidationException;
88
import org.javawebstack.validator.ValidationResult;
99
import org.javawebstack.validator.Validator;
1010

11-
import javax.servlet.MultipartConfigElement;
12-
import javax.servlet.http.HttpServletRequest;
13-
import javax.servlet.http.HttpServletResponse;
1411
import java.io.ByteArrayOutputStream;
1512
import java.io.IOException;
1613
import java.io.InputStream;
1714
import java.nio.charset.StandardCharsets;
1815
import java.util.*;
16+
import java.util.stream.Collectors;
17+
import java.util.stream.Stream;
1918

2019
public class Exchange {
2120

@@ -26,22 +25,18 @@ public static Exchange current() {
2625
}
2726

2827
private final HTTPServer server;
29-
private final HttpMethod method;
30-
private final String path;
28+
private final HTTPMethod method;
3129
private byte[] body = null;
3230
private final Map<String, Object> pathVariables = new HashMap<>();
3331
private final AbstractObject queryParameters;
34-
private final HttpServletRequest request;
35-
private final HttpServletResponse response;
32+
private final IHTTPSocket socket;
3633
private final Map<String, Object> attributes = new HashMap<>();
3734

38-
public Exchange(HTTPServer server, HttpServletRequest request, HttpServletResponse response) {
35+
public Exchange(HTTPServer server, IHTTPSocket socket) {
3936
this.server = server;
40-
this.request = request;
41-
this.response = response;
42-
this.path = request.getPathInfo();
43-
this.method = "websocket".equalsIgnoreCase(request.getHeader("Upgrade")) ? HttpMethod.WEBSOCKET : HttpMethod.valueOf(request.getMethod());
44-
this.queryParameters = AbstractElement.fromFormData(request.getQueryString()).object();
37+
this.socket = socket;
38+
this.method = "websocket".equalsIgnoreCase(socket.getRequestHeader("upgrade")) ? HTTPMethod.WEBSOCKET : socket.getRequestMethod();
39+
this.queryParameters = AbstractElement.fromFormData(socket.getRequestQuery()).object();
4540
}
4641

4742
public <T> T body(Class<T> clazz) {
@@ -91,22 +86,23 @@ public HTTPServer getServer() {
9186
return server;
9287
}
9388

94-
public HttpMethod getMethod() {
89+
public HTTPMethod getMethod() {
9590
return method;
9691
}
9792

9893
public String getPath() {
99-
return path;
94+
return socket.getRequestPath();
10095
}
10196

10297
public String getContentType() {
103-
return request.getContentType() != null ? request.getContentType() : "";
98+
String contentType = socket.getRequestHeader("content-type");
99+
return contentType != null ? contentType : "";
104100
}
105101

106102
public byte[] read() {
107103
ByteArrayOutputStream baos = new ByteArrayOutputStream();
108104
try {
109-
InputStream is = request.getInputStream();
105+
InputStream is = socket.getInputStream();
110106
byte[] data = new byte[1024];
111107
int r;
112108
while (is.available() > 0) {
@@ -126,17 +122,17 @@ public Exchange write(String data) {
126122

127123
public Exchange write(byte[] bytes) {
128124
try {
129-
response.getOutputStream().write(bytes);
130-
response.getOutputStream().flush();
125+
socket.getOutputStream().write(bytes);
126+
socket.getOutputStream().flush();
131127
} catch (IOException ignored) {
132128
}
133129
return this;
134130
}
135131

136132
public Exchange write(byte[] bytes, int offset, int length) {
137133
try {
138-
response.getOutputStream().write(bytes, offset, length);
139-
response.getOutputStream().flush();
134+
socket.getOutputStream().write(bytes, offset, length);
135+
socket.getOutputStream().flush();
140136
} catch (IOException ignored) {
141137
}
142138
return this;
@@ -153,49 +149,50 @@ public Exchange write(InputStream stream) throws IOException {
153149

154150
public Exchange close() {
155151
try {
156-
response.getOutputStream().close();
152+
socket.close();
157153
} catch (IOException ignored) {
158154
}
159155
return this;
160156
}
161157

162158
public Exchange header(String header, String value) {
163-
if (header.equalsIgnoreCase("content-type")) {
164-
response.setContentType(value);
165-
return this;
166-
}
167-
response.setHeader(header, value);
159+
socket.setResponseHeader(header, value);
168160
return this;
169161
}
170162

171163
public Exchange status(int code) {
172-
response.setStatus(code);
164+
socket.setResponseStatus(code);
173165
return this;
174166
}
175167

176168
public String header(String header) {
177-
return request.getHeader(header);
169+
return socket.getRequestHeader(header);
178170
}
179171

180172
public Exchange redirect(String url) {
181-
response.setStatus(302);
173+
socket.setResponseStatus(302);
174+
socket.setResponseHeader("location", url);
182175
try {
183-
response.sendRedirect(url);
184-
} catch (IOException ex) {
185-
throw new RuntimeException(ex);
176+
socket.writeHeaders();
177+
} catch (IOException e) {
178+
e.printStackTrace();
186179
}
187180
return this;
188181
}
189182

190183
public List<Locale> locales() {
191-
return Collections.list(request.getLocales());
184+
String locale = socket.getRequestHeader("locale");
185+
if(locale == null)
186+
return new ArrayList<>();
187+
return Stream.of(locale.split(" ?,")).map(s -> s.split(";")[0]).map(Locale::forLanguageTag).collect(Collectors.toList());
192188
}
193189

194190
public Locale locale(Locale... possible) {
191+
List<Locale> requested = locales();
195192
if (possible.length == 0)
196-
return request.getLocale();
193+
return requested.size() > 0 ? requested.get(0) : null;
197194
List<Locale> possibleList = Arrays.asList(possible);
198-
for (Locale l : locales()) {
195+
for (Locale l : requested) {
199196
if (possibleList.contains(l))
200197
return l;
201198
}
@@ -209,15 +206,11 @@ public Exchange contentType(MimeType type) {
209206
public Exchange contentType(String contentType) {
210207
if (contentType == null || contentType.equals(""))
211208
return contentType("text/plain");
212-
return header("Content-Type", contentType);
213-
}
214-
215-
public HttpServletRequest rawRequest() {
216-
return request;
209+
return header("content-type", contentType);
217210
}
218211

219-
public HttpServletResponse rawResponse() {
220-
return response;
212+
public IHTTPSocket socket() {
213+
return socket;
221214
}
222215

223216
public <T> T attrib(String key) {
@@ -255,7 +248,7 @@ public <T> T query(String name, Class<T> type, T defaultValue) {
255248
}
256249

257250
public String remoteAddr() {
258-
return request.getRemoteAddr();
251+
return socket.getRemoteAddress();
259252
}
260253

261254
public Map<String, Object> getPathVariables() {
@@ -299,24 +292,4 @@ protected static AbstractElement getPathElement(AbstractElement source, String p
299292
return getPathElement(getPathElement(source, spl[0]), path.substring(spl[0].length() + 1));
300293
}
301294

302-
public Exchange enableMultipart() {
303-
enableMultipart(System.getProperty("java.io.tmpdir"));
304-
return this;
305-
}
306-
307-
public Exchange enableMultipart(String location) {
308-
enableMultipart(location, -1L);
309-
return this;
310-
}
311-
312-
public Exchange enableMultipart(String location, long maxFileSize) {
313-
enableMultipart(location, maxFileSize, 1_048_576);
314-
return this;
315-
}
316-
317-
318-
public Exchange enableMultipart(String location, long maxFileSize, int fileSizeThreshold) {
319-
request.setAttribute("org.eclipse.jetty.multipartConfig", new MultipartConfigElement(location, maxFileSize, -1L, fileSizeThreshold));
320-
return this;
321-
}
322295
}

src/main/java/org/javawebstack/httpserver/HTTPMethod.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public enum HTTPMethod {
1010
HEAD,
1111
OPTIONS,
1212
TRACE,
13-
CONNECT
13+
CONNECT,
14+
WEBSOCKET
1415

1516
}

0 commit comments

Comments
 (0)