changeset 1194:bd0420fb3dd0

handle ParseException in webserver
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 26 Feb 2018 16:29:07 -0700
parents 9f522cfe0c30
children 9a57f0b16c2b
files src/luan/webserver/Connection.java src/luan/webserver/RequestParser.java src/luan/webserver/Status.java
diffstat 3 files changed, 66 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
diff -r 9f522cfe0c30 -r bd0420fb3dd0 src/luan/webserver/Connection.java
--- a/src/luan/webserver/Connection.java	Mon Feb 26 15:43:32 2018 -0700
+++ b/src/luan/webserver/Connection.java	Mon Feb 26 16:29:07 2018 -0700
@@ -27,76 +27,81 @@
 	private void handle() {
 		try {
 			Request request = new Request();
-			{
-				InputStream in = socket.getInputStream();
-				byte[] a = new byte[8192];
-				int endOfHeader;
-				int size = 0;
-				int left = a.length;
-				outer: while(true) {
-					int n = in.read(a,size,left);
-					if( n == -1 ) {
-						if( size == 0 ) {
-							socket.close();
-							return;
-						}
-						throw new IOException("unexpected end of input at "+size);
-					}
-					size += n;
-					for( int i=0; i<=size-4; i++ ) {
-						if( a[i]=='\r' && a[i+1]=='\n' && a[i+2]=='\r' && a[i+3]=='\n' ) {
-							endOfHeader = i + 4;
-							break outer;
-						}
-					}
-					left -= n;
-					if( left == 0 ) {
-						byte[] a2 = new byte[2*a.length];
-						System.arraycopy(a,0,a2,0,size);
-						a = a2;
-						left = a.length - size;
-					}
-				}
-				String rawHead = new String(a,0,endOfHeader);
-//System.out.println(rawHead);
-				request.rawHead = rawHead;
-				RequestParser parser = new RequestParser(request);
-				parser.parseHead();
-	
-				String lenStr = (String)request.headers.get("content-length");
-				if( lenStr != null ) {
-					int len = Integer.parseInt(lenStr);
-					byte[] body = new byte[len];
-					size -= endOfHeader;
-					System.arraycopy(a,endOfHeader,body,0,size);
-					while( size < len ) {
-						int n = in.read(body,size,len-size);
+			Response response;
+			try {
+				{
+					InputStream in = socket.getInputStream();
+					byte[] a = new byte[8192];
+					int endOfHeader;
+					int size = 0;
+					int left = a.length;
+					outer: while(true) {
+						int n = in.read(a,size,left);
 						if( n == -1 ) {
+							if( size == 0 ) {
+								socket.close();
+								return;
+							}
 							throw new IOException("unexpected end of input at "+size);
 						}
 						size += n;
+						for( int i=0; i<=size-4; i++ ) {
+							if( a[i]=='\r' && a[i+1]=='\n' && a[i+2]=='\r' && a[i+3]=='\n' ) {
+								endOfHeader = i + 4;
+								break outer;
+							}
+						}
+						left -= n;
+						if( left == 0 ) {
+							byte[] a2 = new byte[2*a.length];
+							System.arraycopy(a,0,a2,0,size);
+							a = a2;
+							left = a.length - size;
+						}
 					}
-					request.body = body;
+					String rawHead = new String(a,0,endOfHeader);
+//System.out.println(rawHead);
+					request.rawHead = rawHead;
+					RequestParser parser = new RequestParser(request);
+					parser.parseHead();
+		
+					String lenStr = (String)request.headers.get("content-length");
+					if( lenStr != null ) {
+						int len = Integer.parseInt(lenStr);
+						byte[] body = new byte[len];
+						size -= endOfHeader;
+						System.arraycopy(a,endOfHeader,body,0,size);
+						while( size < len ) {
+							int n = in.read(body,size,len-size);
+							if( n == -1 ) {
+								throw new IOException("unexpected end of input at "+size);
+							}
+							size += n;
+						}
+						request.body = body;
 //System.out.println(new String(request.body));
-				}
-
-				String contentType = (String)request.headers.get("content-type");
-				if( contentType != null ) {
-					if( request.body == null ) {
-						logger.error("body is null");
-					} else {
-						if( "application/x-www-form-urlencoded".equals(contentType) ) {
-							parser.parseUrlencoded();
-						} else if( contentType.startsWith("multipart/form-data;") ) {
-							parser.parseMultipart();
+					}
+	
+					String contentType = (String)request.headers.get("content-type");
+					if( contentType != null ) {
+						if( request.body == null ) {
+							logger.error("body is null");
 						} else {
-							logger.error("unknown content type: "+contentType);
+							if( "application/x-www-form-urlencoded".equals(contentType) ) {
+								parser.parseUrlencoded();
+							} else if( contentType.startsWith("multipart/form-data;") ) {
+								parser.parseMultipart();
+							} else {
+								logger.error("unknown content type: "+contentType);
+							}
 						}
 					}
 				}
+				response = server.handler.handle(request);
+			} catch(ParseException e) {
+				logger.warn("",e);
+				response = Response.errorResponse(Status.BAD_REQUEST,e.toString());
 			}
-
-			Response response = server.handler.handle(request);
 			response.headers.put("connection","close");
 			response.headers.put("content-length",Long.toString(response.body.length));
 			byte[] header = response.toHeaderString().getBytes();
@@ -108,8 +113,6 @@
 			socket.close();
 		} catch(IOException e) {
 			logger.info("",e);
-		} catch(ParseException e) {
-			logger.warn("",e);
 		}
 	}
 
diff -r 9f522cfe0c30 -r bd0420fb3dd0 src/luan/webserver/RequestParser.java
--- a/src/luan/webserver/RequestParser.java	Mon Feb 26 15:43:32 2018 -0700
+++ b/src/luan/webserver/RequestParser.java	Mon Feb 26 16:29:07 2018 -0700
@@ -87,7 +87,7 @@
 	}
 
 	private boolean queryChar() {
-		return safePathChar() || parser.anyOf("?");
+		return safePathChar() || parser.anyOf("?\\\"");
 	}
 
 	// where did I get this?
diff -r 9f522cfe0c30 -r bd0420fb3dd0 src/luan/webserver/Status.java
--- a/src/luan/webserver/Status.java	Mon Feb 26 15:43:32 2018 -0700
+++ b/src/luan/webserver/Status.java	Mon Feb 26 16:29:07 2018 -0700
@@ -37,6 +37,7 @@
 	public static final Status OK = newStatus(200,"OK");
 	public static final Status MOVED_PERMANENTLY = newStatus(301,"Moved Permanently");
 	public static final Status FOUND = newStatus(302,"Found");
+	public static final Status BAD_REQUEST = newStatus(400,"Bad Request");
 	public static final Status NOT_FOUND = newStatus(404,"Not Found");
 	public static final Status INTERNAL_SERVER_ERROR = newStatus(500,"Internal Server Error");
 }