comparison src/luan/webserver/RequestParser.java @ 1198:9d3835e88204

better query handling
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 27 Feb 2018 21:28:24 -0700
parents 886e14903c1e
children 1e23b913c327
comparison
equal deleted inserted replaced
1197:886e14903c1e 1198:9d3835e88204
7 import luan.lib.parser.Parser; 7 import luan.lib.parser.Parser;
8 import luan.lib.parser.ParseException; 8 import luan.lib.parser.ParseException;
9 9
10 10
11 final class RequestParser { 11 final class RequestParser {
12 private static final Logger logger = LoggerFactory.getLogger(Connection.class); 12 private static final Logger logger = LoggerFactory.getLogger(RequestParser.class);
13 private final Request request; 13 private final Request request;
14 private Parser parser; 14 private Parser parser;
15 15
16 RequestParser(Request request) { 16 RequestParser(Request request) {
17 this.request = request; 17 this.request = request;
18 } 18 }
19 19
20 void parseUrlencoded() throws ParseException { 20 void parseUrlencoded() throws ParseException {
21 if( request.body == null ) { 21 if( request.body == null ) {
22 logger.error("body is null\n"+request.rawHead); 22 logger.warn("body is null\n"+request.rawHead);
23 return; 23 return;
24 } 24 }
25 this.parser = new Parser(Util.toString(request.body)); 25 this.parser = new Parser(Util.toString(request.body));
26 parseQuery(); 26 parseQuery();
27 require( parser.endOfInput() ); 27 require( parser.endOfInput() );
72 while( safePathChar() || parser.anyOf("&=") ); 72 while( safePathChar() || parser.anyOf("&=") );
73 request.path = Util.urlDecode( parser.textFrom(start) ); 73 request.path = Util.urlDecode( parser.textFrom(start) );
74 } 74 }
75 75
76 private void parseQuery() throws ParseException { 76 private void parseQuery() throws ParseException {
77 while(true) { 77 do {
78 while( parser.match('&') );
79 int start = parser.currentIndex(); 78 int start = parser.currentIndex();
80 if( !queryChar() )
81 return;
82 while( queryChar() ); 79 while( queryChar() );
83 String name = Util.urlDecode( parser.textFrom(start) ); 80 String name = Util.urlDecode( parser.textFrom(start) );
84 String value; 81 String value = null;
85 if( parser.match('=') ) { 82 if( parser.match('=') ) {
86 start = parser.currentIndex(); 83 start = parser.currentIndex();
87 while( queryChar() ); 84 while( queryChar() || parser.match('=') );
88 value = Util.urlDecode( parser.textFrom(start) ); 85 value = Util.urlDecode( parser.textFrom(start) );
89 } else { 86 }
90 value = ""; 87 if( name.length() > 0 || value != null ) {
91 } 88 if( value==null )
92 Util.add(request.parameters,name,value); 89 value = "";
93 } 90 Util.add(request.parameters,name,value);
91 }
92 } while( parser.match('&') );
94 } 93 }
95 94
96 private boolean queryChar() { 95 private boolean queryChar() {
97 return safePathChar() || parser.anyOf("?\\\""); 96 return parser.noneOf("=&# \t\n\f\r\u000b");
98 } 97 }
99 98
100 // where did I get this? 99 // where did I get this?
101 private boolean safePathChar() { 100 private boolean safePathChar() {
102 return parser.inCharRange('A','Z') 101 return parser.inCharRange('A','Z')
193 192
194 private static final String contentTypeStart = "multipart/form-data; boundary="; 193 private static final String contentTypeStart = "multipart/form-data; boundary=";
195 194
196 void parseMultipart() throws ParseException { 195 void parseMultipart() throws ParseException {
197 if( request.body == null ) { 196 if( request.body == null ) {
198 logger.error("body is null\n"+request.rawHead); 197 logger.warn("body is null\n"+request.rawHead);
199 return; 198 return;
200 } 199 }
201 String contentType = (String)request.headers.get("content-type"); 200 String contentType = (String)request.headers.get("content-type");
202 if( !contentType.startsWith(contentTypeStart) ) 201 if( !contentType.startsWith(contentTypeStart) )
203 throw new RuntimeException(contentType); 202 throw new RuntimeException(contentType);