annotate src/goodjava/webserver/RequestParser.java @ 1522:bafe6a6797ce

blasma.html
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 28 Jun 2020 13:13:19 -0600
parents fb003c4003dd
children fa066aaa068c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1402
27efb1fcbcb5 move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents: 1371
diff changeset
1 package goodjava.webserver;
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
2
1212
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
3 import java.io.UnsupportedEncodingException;
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
4 import java.net.URLDecoder;
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
5 import java.util.List;
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
6 import java.util.ArrayList;
1402
27efb1fcbcb5 move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents: 1371
diff changeset
7 import goodjava.logging.Logger;
27efb1fcbcb5 move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents: 1371
diff changeset
8 import goodjava.logging.LoggerFactory;
27efb1fcbcb5 move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents: 1371
diff changeset
9 import goodjava.parser.Parser;
27efb1fcbcb5 move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents: 1371
diff changeset
10 import goodjava.parser.ParseException;
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
11
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
12
1144
ae0a048f3bc7 webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1143
diff changeset
13 final class RequestParser {
1198
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
14 private static final Logger logger = LoggerFactory.getLogger(RequestParser.class);
1144
ae0a048f3bc7 webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1143
diff changeset
15 private final Request request;
ae0a048f3bc7 webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1143
diff changeset
16 private Parser parser;
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
17
1144
ae0a048f3bc7 webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1143
diff changeset
18 RequestParser(Request request) {
ae0a048f3bc7 webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1143
diff changeset
19 this.request = request;
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
20 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
21
1266
05934fbf635a content-type "application/x-www-form-urlencoded; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1259
diff changeset
22 void parseUrlencoded(String charset) throws ParseException, UnsupportedEncodingException {
1197
886e14903c1e better Content-Type handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1194
diff changeset
23 if( request.body == null ) {
1198
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
24 logger.warn("body is null\n"+request.rawHead);
1197
886e14903c1e better Content-Type handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1194
diff changeset
25 return;
886e14903c1e better Content-Type handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1194
diff changeset
26 }
1266
05934fbf635a content-type "application/x-www-form-urlencoded; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1259
diff changeset
27 this.parser = new Parser(Util.toString(request.body,charset));
1144
ae0a048f3bc7 webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1143
diff changeset
28 parseQuery();
ae0a048f3bc7 webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1143
diff changeset
29 require( parser.endOfInput() );
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
30 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
31
1144
ae0a048f3bc7 webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1143
diff changeset
32 void parseHead() throws ParseException {
ae0a048f3bc7 webserver - handle POST params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1143
diff changeset
33 this.parser = new Parser(request.rawHead);
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
34 parseRequestLine();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
35 while( !parser.match("\r\n") ) {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
36 parserHeaderField();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
37 }
1146
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
38 parseCookies();
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
39 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
40
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
41 private void parseRequestLine() throws ParseException {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
42 parseMethod();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
43 require( parser.match(' ') );
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
44 parseRawPath();
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
45 require( parser.match(' ') );
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
46 parseProtocol();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
47 require( parser.match("\r\n") );
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
48 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
49
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
50 private void parseMethod() throws ParseException {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
51 int start = parser.currentIndex();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
52 if( !methodChar() )
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
53 throw new ParseException(parser,"no method");
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
54 while( methodChar() );
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
55 request.method = parser.textFrom(start);
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
56 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
57
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
58 private boolean methodChar() {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
59 return parser.inCharRange('A','Z');
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
60 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
61
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
62 private void parseRawPath() throws ParseException {
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
63 int start = parser.currentIndex();
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
64 parsePath();
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
65 if( parser.match('?') )
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
66 parseQuery();
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
67 request.rawPath = parser.textFrom(start);
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
68 }
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
69
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
70 private void parsePath() throws ParseException {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
71 int start = parser.currentIndex();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
72 if( !parser.match('/') )
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
73 throw new ParseException(parser,"bad path");
1221
b99947af8b79 better path parsing
Franklin Schmidt <fschmidt@gmail.com>
parents: 1212
diff changeset
74 while( parser.noneOf(" ?#") );
1212
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
75 request.path = urlDecode( parser.textFrom(start) );
1371
4c5548a61d4f add Request.originalPath
Franklin Schmidt <fschmidt@gmail.com>
parents: 1347
diff changeset
76 request.originalPath = request.path;
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
77 }
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
78
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
79 private void parseQuery() throws ParseException {
1198
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
80 do {
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
81 int start = parser.currentIndex();
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
82 while( queryChar() );
1212
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
83 String name = urlDecode( parser.textFrom(start) );
1198
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
84 String value = null;
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
85 if( parser.match('=') ) {
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
86 start = parser.currentIndex();
1198
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
87 while( queryChar() || parser.match('=') );
1212
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
88 value = urlDecode( parser.textFrom(start) );
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
89 }
1198
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
90 if( name.length() > 0 || value != null ) {
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
91 if( value==null )
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
92 value = "";
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
93 Util.add(request.parameters,name,value);
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
94 }
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
95 } while( parser.match('&') );
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
96 }
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
97
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
98 private boolean queryChar() {
1198
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
99 return parser.noneOf("=&# \t\n\f\r\u000b");
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
100 }
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
101
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
102 private void parseProtocol() throws ParseException {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
103 int start = parser.currentIndex();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
104 if( !(
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
105 parser.match("HTTP/")
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
106 && parser.inCharRange('0','9')
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
107 && parser.match('.')
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
108 && parser.inCharRange('0','9')
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
109 ) )
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
110 throw new ParseException(parser,"bad protocol");
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
111 request.protocol = parser.textFrom(start);
1237
275d1b52dbce add Request.scheme
Franklin Schmidt <fschmidt@gmail.com>
parents: 1221
diff changeset
112 request.scheme = "http";
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
113 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
114
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
115
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
116 private void parserHeaderField() throws ParseException {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
117 String name = parseName();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
118 require( parser.match(':') );
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
119 while( parser.anyOf(" \t") );
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
120 String value = parseValue();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
121 while( parser.anyOf(" \t") );
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
122 require( parser.match("\r\n") );
1146
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
123 Util.add(request.headers,name,value);
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
124 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
125
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
126 private String parseName() throws ParseException {
1148
49fb4e83484f webserver - change headers to lower case
Franklin Schmidt <fschmidt@gmail.com>
parents: 1147
diff changeset
127 int start = parser.currentIndex();
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
128 require( tokenChar() );
1148
49fb4e83484f webserver - change headers to lower case
Franklin Schmidt <fschmidt@gmail.com>
parents: 1147
diff changeset
129 while( tokenChar() );
49fb4e83484f webserver - change headers to lower case
Franklin Schmidt <fschmidt@gmail.com>
parents: 1147
diff changeset
130 return parser.textFrom(start).toLowerCase();
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
131 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
132
1148
49fb4e83484f webserver - change headers to lower case
Franklin Schmidt <fschmidt@gmail.com>
parents: 1147
diff changeset
133 private String parseValue() throws ParseException {
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
134 int start = parser.currentIndex();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
135 while( !testEndOfValue() )
1148
49fb4e83484f webserver - change headers to lower case
Franklin Schmidt <fschmidt@gmail.com>
parents: 1147
diff changeset
136 require( parser.anyChar() );
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
137 return parser.textFrom(start);
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
138 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
139
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
140 private boolean testEndOfValue() {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
141 parser.begin();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
142 while( parser.anyOf(" \t") );
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
143 boolean b = parser.endOfInput() || parser.anyOf("\r\n");
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
144 parser.failure(); // rollback
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
145 return b;
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
146 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
147
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
148 private void require(boolean b) throws ParseException {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
149 if( !b )
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
150 throw new ParseException(parser,"failed");
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
151 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
152
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
153 boolean tokenChar() {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
154 if( parser.endOfInput() )
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
155 return false;
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
156 char c = parser.currentChar();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
157 if( 32 <= c && c <= 126 && "()<>@,;:\\\"/[]?={} \t\r\n".indexOf(c) == -1 ) {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
158 parser.anyChar();
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
159 return true;
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
160 } else {
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
161 return false;
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
162 }
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
163 }
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
164
1146
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
165
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
166 private void parseCookies() throws ParseException {
1148
49fb4e83484f webserver - change headers to lower case
Franklin Schmidt <fschmidt@gmail.com>
parents: 1147
diff changeset
167 String text = (String)request.headers.get("cookie");
1146
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
168 if( text == null )
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
169 return;
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
170 this.parser = new Parser(text);
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
171 while(true) {
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
172 int start = parser.currentIndex();
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
173 while( parser.noneOf("=;") );
1212
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
174 String name = urlDecode( parser.textFrom(start) );
1146
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
175 if( parser.match('=') ) {
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
176 start = parser.currentIndex();
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
177 while( parser.noneOf(";") );
1256
c147e2e877e3 allow subclassing of HttpServicer
Franklin Schmidt <fschmidt@gmail.com>
parents: 1237
diff changeset
178 String value = parser.textFrom(start);
c147e2e877e3 allow subclassing of HttpServicer
Franklin Schmidt <fschmidt@gmail.com>
parents: 1237
diff changeset
179 int len = value.length();
c147e2e877e3 allow subclassing of HttpServicer
Franklin Schmidt <fschmidt@gmail.com>
parents: 1237
diff changeset
180 if( value.charAt(0)=='"' && value.charAt(len-1)=='"' )
c147e2e877e3 allow subclassing of HttpServicer
Franklin Schmidt <fschmidt@gmail.com>
parents: 1237
diff changeset
181 value = value.substring(1,len-1);
c147e2e877e3 allow subclassing of HttpServicer
Franklin Schmidt <fschmidt@gmail.com>
parents: 1237
diff changeset
182 value = urlDecode(value);
1146
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
183 request.cookies.put(name,value);
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
184 }
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
185 if( parser.endOfInput() )
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
186 return;
1208
1e23b913c327 minor cookie parsing fix
Franklin Schmidt <fschmidt@gmail.com>
parents: 1198
diff changeset
187 require( parser.match(';') );
1e23b913c327 minor cookie parsing fix
Franklin Schmidt <fschmidt@gmail.com>
parents: 1198
diff changeset
188 parser.match(' '); // optional for bad browsers
1143
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
189 }
3bf5190b3c77 webserver - handle GET params
Franklin Schmidt <fschmidt@gmail.com>
parents: 1137
diff changeset
190 }
1146
2dda3c92a473 webserver - implement cookies
Franklin Schmidt <fschmidt@gmail.com>
parents: 1145
diff changeset
191
1147
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
192
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
193 private static final String contentTypeStart = "multipart/form-data; boundary=";
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
194
1266
05934fbf635a content-type "application/x-www-form-urlencoded; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1259
diff changeset
195 void parseMultipart() throws ParseException, UnsupportedEncodingException {
1197
886e14903c1e better Content-Type handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1194
diff changeset
196 if( request.body == null ) {
1198
9d3835e88204 better query handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1197
diff changeset
197 logger.warn("body is null\n"+request.rawHead);
1197
886e14903c1e better Content-Type handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1194
diff changeset
198 return;
886e14903c1e better Content-Type handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1194
diff changeset
199 }
1148
49fb4e83484f webserver - change headers to lower case
Franklin Schmidt <fschmidt@gmail.com>
parents: 1147
diff changeset
200 String contentType = (String)request.headers.get("content-type");
1147
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
201 if( !contentType.startsWith(contentTypeStart) )
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
202 throw new RuntimeException(contentType);
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
203 String boundary = "--"+contentType.substring(contentTypeStart.length());
1266
05934fbf635a content-type "application/x-www-form-urlencoded; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1259
diff changeset
204 this.parser = new Parser(Util.toString(request.body,null));
1259
e8020216dee7 add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1258
diff changeset
205 //System.out.println(this.parser.text);
1147
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
206 require( parser.match(boundary) );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
207 boundary = "\r\n" + boundary;
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
208 while( !parser.match("--\r\n") ) {
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
209 require( parser.match("\r\n") );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
210 require( parser.match("Content-Disposition: form-data; name=") );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
211 String name = quotedString();
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
212 String filename = null;
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
213 boolean isBinary = false;
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
214 if( parser.match("; filename=") ) {
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
215 filename = quotedString();
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
216 require( parser.match("\r\n") );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
217 require( parser.match("Content-Type: ") );
1259
e8020216dee7 add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1258
diff changeset
218 int start = parser.currentIndex();
e8020216dee7 add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1258
diff changeset
219 if( parser.match("application/") ) {
1147
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
220 isBinary = true;
1299
c214cd0413dd allow upload images
Franklin Schmidt <fschmidt@gmail.com>
parents: 1266
diff changeset
221 } else if( parser.match("image/") ) {
c214cd0413dd allow upload images
Franklin Schmidt <fschmidt@gmail.com>
parents: 1266
diff changeset
222 isBinary = true;
1259
e8020216dee7 add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1258
diff changeset
223 } else if( parser.match("text/") ) {
1147
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
224 isBinary = false;
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
225 } else
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
226 throw new ParseException(parser,"bad file content-type");
1259
e8020216dee7 add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1258
diff changeset
227 while( parser.inCharRange('a','z') || parser.anyOf("-.") );
e8020216dee7 add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1258
diff changeset
228 contentType = parser.textFrom(start);
1147
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
229 }
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
230 require( parser.match("\r\n") );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
231 require( parser.match("\r\n") );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
232 int start = parser.currentIndex();
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
233 while( !parser.test(boundary) ) {
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
234 require( parser.anyChar() );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
235 }
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
236 String value = parser.textFrom(start);
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
237 if( filename == null ) {
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
238 Util.add(request.parameters,name,value);
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
239 } else {
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
240 Object content = isBinary ? Util.toBytes(value) : value;
1259
e8020216dee7 add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1258
diff changeset
241 Request.MultipartFile mf = new Request.MultipartFile(filename,contentType,content);
1147
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
242 Util.add(request.parameters,name,mf);
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
243 }
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
244 require( parser.match(boundary) );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
245 }
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
246 }
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
247
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
248 private String quotedString() throws ParseException {
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
249 StringBuilder sb = new StringBuilder();
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
250 require( parser.match('"') );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
251 while( !parser.match('"') ) {
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
252 if( parser.match("\\\"") ) {
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
253 sb.append('"');
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
254 } else {
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
255 require( parser.anyChar() );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
256 sb.append( parser.lastChar() );
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
257 }
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
258 }
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
259 return sb.toString();
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
260 }
30d87b7d1d62 webserver - support multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents: 1146
diff changeset
261
1212
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
262 private String urlDecode(String s) throws ParseException {
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
263 try {
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
264 return URLDecoder.decode(s,"UTF-8");
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
265 } catch(UnsupportedEncodingException e) {
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
266 parser.rollback();
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
267 throw new ParseException(parser,e);
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
268 } catch(IllegalArgumentException e) {
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
269 parser.rollback();
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
270 throw new ParseException(parser,e);
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
271 }
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
272 }
220228bf1af9 better urlDecode error handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1208
diff changeset
273
1258
e4d7a3114fa8 support "Content-Type: application/json; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1256
diff changeset
274 // improve later
1463
fb003c4003dd better application/json handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1402
diff changeset
275 void parseJson(String charset) throws UnsupportedEncodingException {
1258
e4d7a3114fa8 support "Content-Type: application/json; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1256
diff changeset
276 if( request.body == null ) {
e4d7a3114fa8 support "Content-Type: application/json; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1256
diff changeset
277 logger.warn("body is null\n"+request.rawHead);
e4d7a3114fa8 support "Content-Type: application/json; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1256
diff changeset
278 return;
e4d7a3114fa8 support "Content-Type: application/json; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1256
diff changeset
279 }
1463
fb003c4003dd better application/json handling
Franklin Schmidt <fschmidt@gmail.com>
parents: 1402
diff changeset
280 String value = Util.toString(request.body,charset);
1258
e4d7a3114fa8 support "Content-Type: application/json; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1256
diff changeset
281 Util.add(request.parameters,"json",value);
e4d7a3114fa8 support "Content-Type: application/json; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1256
diff changeset
282 }
e4d7a3114fa8 support "Content-Type: application/json; charset=utf-8"
Franklin Schmidt <fschmidt@gmail.com>
parents: 1256
diff changeset
283
1137
c123ee15f99b add webserver
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
284 }