Mercurial Hosting > luan
comparison src/luan/webserver/RequestParser.java @ 1147:30d87b7d1d62
webserver - support multipart/form-data
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 01 Feb 2018 22:06:37 -0700 |
parents | 2dda3c92a473 |
children | 49fb4e83484f |
comparison
equal
deleted
inserted
replaced
1146:2dda3c92a473 | 1147:30d87b7d1d62 |
---|---|
13 RequestParser(Request request) { | 13 RequestParser(Request request) { |
14 this.request = request; | 14 this.request = request; |
15 } | 15 } |
16 | 16 |
17 void parseUrlencoded() throws ParseException { | 17 void parseUrlencoded() throws ParseException { |
18 this.parser = new Parser(request.body); | 18 this.parser = new Parser(Util.toString(request.body)); |
19 parseQuery(); | 19 parseQuery(); |
20 require( parser.endOfInput() ); | 20 require( parser.endOfInput() ); |
21 } | 21 } |
22 | 22 |
23 void parseHead() throws ParseException { | 23 void parseHead() throws ParseException { |
193 return; | 193 return; |
194 require( parser.match("; ") ); | 194 require( parser.match("; ") ); |
195 } | 195 } |
196 } | 196 } |
197 | 197 |
198 | |
199 private static final String contentTypeStart = "multipart/form-data; boundary="; | |
200 | |
201 void parseMultipart() throws ParseException { | |
202 String contentType = (String)request.headers.get("Content-Type"); | |
203 if( !contentType.startsWith(contentTypeStart) ) | |
204 throw new RuntimeException(contentType); | |
205 String boundary = "--"+contentType.substring(contentTypeStart.length()); | |
206 this.parser = new Parser(Util.toString(request.body)); | |
207 require( parser.match(boundary) ); | |
208 boundary = "\r\n" + boundary; | |
209 while( !parser.match("--\r\n") ) { | |
210 require( parser.match("\r\n") ); | |
211 require( parser.match("Content-Disposition: form-data; name=") ); | |
212 String name = quotedString(); | |
213 String filename = null; | |
214 boolean isBinary = false; | |
215 if( parser.match("; filename=") ) { | |
216 filename = quotedString(); | |
217 require( parser.match("\r\n") ); | |
218 require( parser.match("Content-Type: ") ); | |
219 if( parser.match("application/octet-stream") ) { | |
220 isBinary = true; | |
221 } else if( parser.match("text/plain") ) { | |
222 isBinary = false; | |
223 } else | |
224 throw new ParseException(parser,"bad file content-type"); | |
225 } | |
226 require( parser.match("\r\n") ); | |
227 require( parser.match("\r\n") ); | |
228 int start = parser.currentIndex(); | |
229 while( !parser.test(boundary) ) { | |
230 require( parser.anyChar() ); | |
231 } | |
232 String value = parser.textFrom(start); | |
233 if( filename == null ) { | |
234 Util.add(request.parameters,name,value); | |
235 } else { | |
236 Object content = isBinary ? Util.toBytes(value) : value; | |
237 Request.MultipartFile mf = new Request.MultipartFile(filename,content); | |
238 Util.add(request.parameters,name,mf); | |
239 } | |
240 require( parser.match(boundary) ); | |
241 } | |
242 } | |
243 | |
244 private String quotedString() throws ParseException { | |
245 StringBuilder sb = new StringBuilder(); | |
246 require( parser.match('"') ); | |
247 while( !parser.match('"') ) { | |
248 if( parser.match("\\\"") ) { | |
249 sb.append('"'); | |
250 } else { | |
251 require( parser.anyChar() ); | |
252 sb.append( parser.lastChar() ); | |
253 } | |
254 } | |
255 return sb.toString(); | |
256 } | |
257 | |
198 } | 258 } |