Mercurial Hosting > luan
changeset 1143:3bf5190b3c77
webserver - handle GET params
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 30 Jan 2018 23:53:28 -0700 |
parents | 0f59eab45f3d |
children | ae0a048f3bc7 |
files | src/luan/modules/http/tools/Dump_mod.luan src/luan/webserver/Request.java src/luan/webserver/RequestHeadParser.java src/luan/webserver/examples/Example.java src/luan/webserver/examples/Params.java |
diffstat | 5 files changed, 111 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/modules/http/tools/Dump_mod.luan Tue Jan 30 18:02:47 2018 -0700 +++ b/src/luan/modules/http/tools/Dump_mod.luan Tue Jan 30 23:53:28 2018 -0700 @@ -1,6 +1,7 @@ local Luan = require "luan:Luan.luan" -local pairs = Luan.pairs -local ipairs = Luan.ipairs +local error = Luan.error +local pairs = Luan.pairs or error() +local ipairs = Luan.ipairs or error() local Io = require "luan:Io.luan" local Http = require "luan:http/Http.luan" java()
--- a/src/luan/webserver/Request.java Tue Jan 30 18:02:47 2018 -0700 +++ b/src/luan/webserver/Request.java Tue Jan 30 23:53:28 2018 -0700 @@ -8,6 +8,7 @@ public class Request { public volatile String rawHead; public volatile String method; + public volatile String rawPath; public volatile String path; public volatile String protocol; // only HTTP/1.1 is accepted public final Map<String,String> headers = Collections.synchronizedMap(new LinkedHashMap<String,String>());
--- 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); + } + } }
--- a/src/luan/webserver/examples/Example.java Tue Jan 30 18:02:47 2018 -0700 +++ b/src/luan/webserver/examples/Example.java Tue Jan 30 23:53:28 2018 -0700 @@ -5,7 +5,9 @@ import java.io.IOException; import java.util.Map; import java.util.HashMap; -import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.EnhancedPatternLayout; +import org.apache.log4j.ConsoleAppender; +import org.apache.log4j.Logger; import luan.webserver.Handler; import luan.webserver.Request; import luan.webserver.Response; @@ -42,6 +44,7 @@ Map<String,Handler> map = new HashMap<String,Handler>(); map.put( "/hello", new Example() ); map.put( "/headers", new Headers() ); + map.put( "/params", new Params() ); Handler handler = new MapHandler(map); handler = new ListHandler( handler, new FileHandler() ); handler = new SafeHandler(handler); @@ -49,8 +52,15 @@ new Server(8080,handler).start(); } + public static void initLogging() { +// Logger.getRootLogger().setLevel(Level.INFO); + EnhancedPatternLayout layout = new EnhancedPatternLayout("%d{HH:mm:ss} %-5p %c - %m%n"); + ConsoleAppender appender = new ConsoleAppender(layout,"System.err"); + Logger.getRootLogger().addAppender(appender); + } + public static void main(String[] args) throws Exception { - BasicConfigurator.configure(); + initLogging(); fancy(); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/webserver/examples/Params.java Tue Jan 30 23:53:28 2018 -0700 @@ -0,0 +1,30 @@ +package luan.webserver.examples; + +import java.io.Writer; +import java.io.OutputStreamWriter; +import java.io.IOException; +import java.util.Map; +import luan.webserver.Handler; +import luan.webserver.Request; +import luan.webserver.Response; +import luan.webserver.ResponseOutputStream; + + +public final class Params implements Handler { + + public Response handle(Request request) { + Response response = new Response(); + response.headers.put( "Content-Type", "text/plain; charset=UTF-8" ); + try { + Writer writer = new OutputStreamWriter( new ResponseOutputStream(response) ); + for( Map.Entry<String,Object> entry : request.parameters.entrySet() ) { + writer.write(entry.getKey()+" = "+entry.getValue()+"\n"); + } + writer.close(); + } catch(IOException e) { + throw new RuntimeException(e); + } + return response; + } + +}