Mercurial Hosting > luan
diff src/luan/webserver/RequestHeadParser.java @ 1143:3bf5190b3c77
webserver - handle GET params
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 30 Jan 2018 23:53:28 -0700 |
parents | c123ee15f99b |
children |
line wrap: on
line diff
--- a/src/luan/webserver/RequestHeadParser.java Tue Jan 30 18:02:47 2018 -0700 +++ b/src/luan/webserver/RequestHeadParser.java Tue Jan 30 23:53:28 2018 -0700 @@ -1,5 +1,9 @@ package luan.webserver; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.List; +import java.util.ArrayList; import luan.lib.parser.Parser; import luan.lib.parser.ParseException; @@ -31,7 +35,7 @@ private void parseRequestLine() throws ParseException { parseMethod(); require( parser.match(' ') ); - parsePath(); + parseRawPath(); require( parser.match(' ') ); parseProtocol(); require( parser.match("\r\n") ); @@ -49,17 +53,64 @@ return parser.inCharRange('A','Z'); } + private void parseRawPath() throws ParseException { + int start = parser.currentIndex(); + parsePath(); + if( parser.match('?') ) + parseQuery(); + request.rawPath = parser.textFrom(start); + } + private void parsePath() throws ParseException { int start = parser.currentIndex(); if( !parser.match('/') ) throw new ParseException(parser,"bad path"); - while( - parser.inCharRange('A','Z') + while( safePathChar() || parser.anyOf("&=") ); + request.path = decode( parser.textFrom(start) ); + } + + private void parseQuery() throws ParseException { + while(true) { + while( parser.match('&') ); + int start = parser.currentIndex(); + if( !queryChar() ) + return; + while( queryChar() ); + String name = decode( parser.textFrom(start) ); + String value; + if( parser.match('=') ) { + start = parser.currentIndex(); + while( queryChar() ); + value = decode( parser.textFrom(start) ); + } else { + value = ""; + } + Object current = request.parameters.get(name); + if( current == null ) { + request.parameters.put(name,value); + } else if( current instanceof List ) { + List list = (List)current; + list.add(value); + } else { + List list = new ArrayList(); + list.add(current); + list.add(value); + request.parameters.put(name,list); + } + } + } + + private boolean queryChar() { + return safePathChar() || parser.anyOf("?"); + } + + // where did I get this? + private boolean safePathChar() { + return parser.inCharRange('A','Z') || parser.inCharRange('a','z') || parser.inCharRange('0','9') - || parser.anyOf("-._~:/?#[]@!$&'()*+,;=`.") - ); - request.path = parser.textFrom(start); + || parser.anyOf("-._~:/[]@!$'()*+,;`.%") + ; } private void parseProtocol() throws ParseException { @@ -135,4 +186,12 @@ return false; } } + + private static String decode(String s) { + try { + return URLDecoder.decode(s,"UTF-8"); + } catch(UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } }