Skip to content

Commit b1aa8b1

Browse files
committed
Add x-www-form-urlencoded body parser / clean up some code
1 parent 1b83170 commit b1aa8b1

File tree

6 files changed

+184
-83
lines changed

6 files changed

+184
-83
lines changed

src/express/Express.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* @author Simon Reinisch
1919
* @implNote Core modul, don't change anything.
2020
* <p>
21-
* An NodeJS like clone written in Java, see README for more information.
21+
* An NodeJS like clone written in Java.
2222
*/
2323
public class Express {
2424

@@ -40,7 +40,7 @@ public void use(HttpRequest middleware) {
4040
/**
4141
* Add an middleware which will be firea BEFORE EACH request-type listener will be fired.
4242
*
43-
* @param context The context where the middleware should listen, see README for information about placeholder.
43+
* @param context The context where the middleware should listen.
4444
* @param middleware An middleware which will be fired if the context matches the requestpath.
4545
*/
4646
public void use(String context, HttpRequest middleware) {
@@ -69,7 +69,7 @@ private void addMiddleware(String requestMethod, String context, HttpRequest mid
6969
/**
7070
* Add an listener for GET request's.
7171
*
72-
* @param context The context, see README for information about placeholder.
72+
* @param context The context.
7373
* @param request An listener which will be fired if the context matches the requestpath.
7474
*/
7575
public void all(String context, HttpRequest request) {
@@ -89,7 +89,7 @@ public void get(String context, HttpRequest request) {
8989
/**
9090
* Add an listener for POST request's.
9191
*
92-
* @param context The context, see README for information about placeholder.
92+
* @param context The context.
9393
* @param request An listener which will be fired if the context matches the requestpath.
9494
*/
9595
public void post(String context, HttpRequest request) {
@@ -109,7 +109,7 @@ public void put(String context, HttpRequest request) {
109109
/**
110110
* Add an listener for DELETE request's.
111111
*
112-
* @param context The context, see README for information about placeholder.
112+
* @param context The context.
113113
* @param request An listener which will be fired if the context matches the requestpath.
114114
*/
115115
public void delete(String context, HttpRequest request) {

src/express/expressfilter/ExpressFilterImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public ExpressFilterImpl(String requestMethod, String context, HttpRequest httpR
3030

3131
this.CONTEXT = context;
3232
this.CONTEXT_PARAMS = context.split("(/)(:|[^:]+|)(:|)");
33-
this.CONTEXT_REGEX = "\\Q" + context.replaceAll(":([^/]+)", "\\\\E([^/]+)\\\\Q") + "\\E";
33+
this.CONTEXT_REGEX = "^\\Q" + context.replaceAll(":([^/]+)", "\\\\E([^/]+)\\\\Q") + "\\E$";
3434
this.CONTEXT_PATTERN = Pattern.compile(CONTEXT_REGEX);
3535
}
3636

@@ -46,7 +46,7 @@ public void handle(Request req, Response res) {
4646
return;
4747
}
4848

49-
// Parse params, see README
49+
// Parse params
5050
HashMap<String, String> params = new HashMap<>();
5151
Matcher matcher = CONTEXT_PATTERN.matcher(requestPath);
5252

src/express/http/Request.java

Lines changed: 78 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,55 @@
88
import java.io.IOException;
99
import java.io.InputStream;
1010
import java.io.OutputStream;
11-
import java.io.UnsupportedEncodingException;
1211
import java.net.URI;
13-
import java.net.URLDecoder;
1412
import java.util.HashMap;
1513
import java.util.List;
16-
import java.util.regex.Matcher;
17-
import java.util.regex.Pattern;
1814

1915
/**
2016
* @author Simon Reinisch
2117
* @implNote Core modul of express, don't change anything.
2218
*/
2319
public class Request {
2420

25-
private final URI URI;
2621
private final HttpExchange HTTP_EXCHANGE;
27-
private final InputStream BODY;
28-
private final Headers HEADER;
29-
private final String CONTENT_TYPE;
30-
private final Authorization AUTH;
22+
private final URI URI; // Request URI
23+
private final InputStream BODY; // Request body
24+
private final Headers HEADERS; // Request Headers
25+
private final String CONTENT_TYPE; // Request content-type
26+
private final Authorization AUTH; // Authorization header parsed
3127

32-
private final HashMap<String, Object> MIDDLEWARE;
28+
private final HashMap<String, Object> MIDDLEWARE; // Middleware Data
29+
private final HashMap<String, Cookie> COOKIES; // Request cookies
30+
private final HashMap<String, String> QUERYS; // URL Querys
31+
private final HashMap<String, String> FORM_QUERYS; // Form Querys (application/x-www-form-urlencoded)
3332

34-
private final HashMap<String, Cookie> COOKIES;
35-
private final HashMap<String, String> QUERYS;
36-
private HashMap<String, String> params;
33+
private HashMap<String, String> params; // URL Params, would be added in ExpressFilterImpl
34+
35+
{
36+
this.MIDDLEWARE = new HashMap<>();
37+
this.params = new HashMap<>();
38+
}
3739

3840
public Request(HttpExchange exchange) {
3941
this.HTTP_EXCHANGE = exchange;
4042
this.URI = exchange.getRequestURI();
41-
this.HEADER = exchange.getRequestHeaders();
43+
this.HEADERS = exchange.getRequestHeaders();
4244
this.BODY = exchange.getRequestBody();
4345

44-
this.CONTENT_TYPE = HEADER.get("Content-Type") == null ? "" : HEADER.get("Content-Type").get(0);
45-
this.AUTH = HEADER.get("Authorization") == null ? null : new Authorization(HEADER.get("Authorization").get(0));
46+
// Check if the request contains an body-content
47+
this.CONTENT_TYPE = HEADERS.get("Content-Type") == null ? "" : HEADERS.get("Content-Type").get(0);
4648

47-
this.MIDDLEWARE = new HashMap<>();
48-
this.params = new HashMap<>();
49+
// Check if the request has an Authorization header
50+
this.AUTH = HEADERS.get("Authorization") == null ? null : new Authorization(HEADERS.get("Authorization").get(0));
4951

50-
this.QUERYS = parseRawQuery(exchange.getRequestURI());
51-
this.COOKIES = parseCookies(exchange.getRequestHeaders());
52+
// Check if the request contains x-www-form-urlencoded form data
53+
this.FORM_QUERYS = CONTENT_TYPE.equals("application/x-www-form-urlencoded")
54+
? RequestUtils.parseRawQuery(RequestUtils.streamToString(BODY))
55+
: new HashMap<>();
56+
57+
// Parse query and cookies, both returns not null if there is nothing
58+
this.QUERYS = RequestUtils.parseRawQuery(exchange.getRequestURI().getRawQuery());
59+
this.COOKIES = RequestUtils.parseCookies(exchange.getRequestHeaders());
5260
}
5361

5462
/**
@@ -92,10 +100,23 @@ public HashMap<String, Cookie> getCookies() {
92100
return COOKIES;
93101
}
94102

103+
/**
104+
* Add an the content from an middleware
105+
*
106+
* @param middleware The middleware
107+
* @param middlewareData The data from the middleware
108+
*/
95109
public void addMiddlewareContent(ExpressFilter middleware, Object middlewareData) {
96110
MIDDLEWARE.put(middleware.getName(), middlewareData);
97111
}
98112

113+
/**
114+
* Get the data from a specific middleware by name (Also the reason
115+
* why the interface ExpressFilter implements a getName())
116+
*
117+
* @param name The middleware name
118+
* @return The middleware object
119+
*/
99120
public Object getMiddlewareContent(String name) {
100121
return MIDDLEWARE.get(name);
101122
}
@@ -104,14 +125,14 @@ public Object getMiddlewareContent(String name) {
104125
* @return The request user-agent.
105126
*/
106127
public String getUserAgent() {
107-
return HEADER.get("User-agent").get(0);
128+
return HEADERS.get("User-agent").get(0);
108129
}
109130

110131
/**
111132
* @return The request host.
112133
*/
113134
public String getHost() {
114-
return HEADER.get("Host").get(0);
135+
return HEADERS.get("Host").get(0);
115136
}
116137

117138
/**
@@ -159,9 +180,18 @@ public boolean hasAuthorization() {
159180
return AUTH != null;
160181
}
161182

183+
/**
184+
* Returns a query from a form which uses the 'application/x-www-form-urlencoded' request header.
185+
*
186+
* @param name The name.
187+
* @return The value, null if there is none.
188+
*/
189+
public String getFormQuery(String name) {
190+
return FORM_QUERYS.get(name);
191+
}
192+
162193
/**
163194
* Returns an param from a dynamic url.
164-
* see README
165195
*
166196
* @param param The param.
167197
* @return The value, null if there is none.
@@ -181,76 +211,48 @@ public String getQuery(String name) {
181211
}
182212

183213
/**
184-
* Set the params.
214+
* Returns all querys from an x-www-form-urlencoded body.
185215
*
186-
* @param params
216+
* @return An entire list of key-values
187217
*/
188-
public void setParams(HashMap<String, String> params) {
189-
this.params = params;
218+
public HashMap<String, String> getFormQuerys() {
219+
return FORM_QUERYS;
190220
}
191221

192222
/**
193-
* Returns an header value.
223+
* Returns all params from the url.
194224
*
195-
* @param header The header name
196-
* @return An list with values.
225+
* @return An entire list of key-values
197226
*/
198-
public List<String> getHeader(String header) {
199-
return HEADER.get(header);
227+
public HashMap<String, String> getParams() {
228+
return params;
200229
}
201230

202231
/**
203-
* Extract the cookies from the 'Cookie' header.
232+
* Return all url-querys.
204233
*
205-
* @param headers The Headers
206-
* @return An hashmap with the cookie name as key and the complete cookie as value.
234+
* @return An entire list of key-values
207235
*/
208-
private static HashMap<String, Cookie> parseCookies(Headers headers) {
209-
HashMap<String, Cookie> cookieList = new HashMap<>();
210-
List<String> headerCookies = headers.get("Cookie");
211-
212-
if (headerCookies == null || headerCookies.size() == 0) {
213-
return cookieList;
214-
}
215-
216-
String hcookies = headerCookies.get(0);
217-
218-
String[] cookies = hcookies.split(";");
219-
for (String cookie : cookies) {
220-
String[] split = cookie.split("=");
221-
String name = split[0].trim();
222-
String value = split[1].trim();
223-
cookieList.put(name, new Cookie(name, value));
224-
}
225-
226-
return cookieList;
236+
public HashMap<String, String> getQuerys() {
237+
return QUERYS;
227238
}
228239

229240
/**
230-
* Method to extract the querys from an url.
241+
* Set the params.
231242
*
232-
* @param uri The uri.
233-
* @return An list with key-values which are encoded in UTF8.
243+
* @param params
234244
*/
235-
private static HashMap<String, String> parseRawQuery(URI uri) {
236-
HashMap<String, String> querys = new HashMap<>();
237-
String rawQuery = uri.getRawQuery();
238-
239-
if (rawQuery == null)
240-
return querys;
241-
242-
Matcher mat = Pattern.compile("(.+?)=(.+?)(&|$)").matcher(rawQuery);
243-
while (mat.find()) {
244-
try {
245-
String key = URLDecoder.decode(mat.group(1), "UTF8");
246-
String val = URLDecoder.decode(mat.group(2), "UTF8");
247-
querys.put(key, val);
248-
} catch (UnsupportedEncodingException e) {
249-
e.printStackTrace();
250-
}
251-
}
252-
253-
return querys;
245+
public void setParams(HashMap<String, String> params) {
246+
this.params = params;
254247
}
255248

249+
/**
250+
* Returns an header value.
251+
*
252+
* @param header The header name
253+
* @return An list with values.
254+
*/
255+
public List<String> getHeader(String header) {
256+
return HEADERS.get(header);
257+
}
256258
}

src/express/http/RequestUtils.java

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package express.http;
2+
3+
import com.sun.net.httpserver.Headers;
4+
import express.http.cookie.Cookie;
5+
6+
import java.io.*;
7+
import java.net.URLDecoder;
8+
import java.util.HashMap;
9+
import java.util.List;
10+
import java.util.regex.Matcher;
11+
import java.util.regex.Pattern;
12+
13+
public class RequestUtils {
14+
15+
/**
16+
* Extract the cookies from the 'Cookie' header.
17+
*
18+
* @param headers The Headers
19+
* @return An hashmap with the cookie name as key and the complete cookie as value.
20+
*/
21+
protected static HashMap<String, Cookie> parseCookies(Headers headers) {
22+
HashMap<String, Cookie> cookieList = new HashMap<>();
23+
List<String> headerCookies = headers.get("Cookie");
24+
25+
if (headerCookies == null || headerCookies.size() == 0) {
26+
return cookieList;
27+
}
28+
29+
String hcookies = headerCookies.get(0);
30+
31+
String[] cookies = hcookies.split(";");
32+
for (String cookie : cookies) {
33+
String[] split = cookie.split("=");
34+
String name = split[0].trim();
35+
String value = split[1].trim();
36+
cookieList.put(name, new Cookie(name, value));
37+
}
38+
39+
return cookieList;
40+
}
41+
42+
/**
43+
* Method to extract the querys from an url.
44+
*
45+
* @param rawQuery The raw query
46+
* @return An list with key-values which are encoded in UTF8.
47+
*/
48+
protected static HashMap<String, String> parseRawQuery(String rawQuery) {
49+
HashMap<String, String> querys = new HashMap<>();
50+
51+
if (rawQuery == null)
52+
return querys;
53+
54+
Matcher mat = Pattern.compile("(.+?)=(.+?)(&|$)").matcher(rawQuery);
55+
while (mat.find()) {
56+
try {
57+
String key = URLDecoder.decode(mat.group(1), "UTF8");
58+
String val = URLDecoder.decode(mat.group(2), "UTF8");
59+
querys.put(key, val);
60+
} catch (UnsupportedEncodingException e) {
61+
e.printStackTrace();
62+
}
63+
}
64+
65+
return querys;
66+
}
67+
68+
/**
69+
* Write all data from an InputStream in an String
70+
*
71+
* @param is The source inputstream
72+
* @return The data as string
73+
*/
74+
public static String streamToString(InputStream is) {
75+
try {
76+
BufferedReader br = new BufferedReader(new InputStreamReader(is));
77+
StringBuffer buffer = new StringBuffer();
78+
String line;
79+
80+
while ((line = br.readLine()) != null)
81+
buffer.append(line);
82+
83+
return buffer.toString();
84+
} catch (IOException e) {
85+
// TODO: Handle error
86+
e.printStackTrace();
87+
}
88+
return null;
89+
}
90+
91+
}

0 commit comments

Comments
 (0)