From f77a757b6d1ec7fdb8bb1414607bec2106d6bd5a Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Wed, 6 Jul 2016 17:34:59 +0200 Subject: [PATCH] Refactored some things in the http package --- src/zutil/net/http/HttpHeader.java | 14 +-- src/zutil/net/http/HttpHeaderParser.java | 104 +++++++++++------- src/zutil/net/http/HttpServer.java | 2 +- test/zutil/net/http/HTTPUploaderTest.java | 57 ---------- .../http/{ => page}/HTTPGuessTheNumber.java | 9 +- 5 files changed, 74 insertions(+), 112 deletions(-) delete mode 100755 test/zutil/net/http/HTTPUploaderTest.java rename test/zutil/net/http/{ => page}/HTTPGuessTheNumber.java (93%) diff --git a/src/zutil/net/http/HttpHeader.java b/src/zutil/net/http/HttpHeader.java index cf66718..460e836 100755 --- a/src/zutil/net/http/HttpHeader.java +++ b/src/zutil/net/http/HttpHeader.java @@ -148,7 +148,7 @@ public class HttpHeader { protected void setIsRequest(boolean request) { this.request = request; } protected void setRequestType(String type){ - this.type = type.trim(); + this.type = type; } protected void setHTTPVersion(float version){ this.version = version; @@ -159,16 +159,10 @@ public class HttpHeader { protected void setRequestURL(String url){ this.url = url.trim().replaceAll("//", "/"); } - protected void putCookie(String key, String value){ - cookies.put(key.trim(), value.trim()); - } - protected void putURLAttribute(String key, String value){ - urlAttributes.put(key.trim(), value.trim()); - } - protected void putHeader(String key, String value){ - headers.put(key.trim(), value.trim()); - } + protected HashMap getHeaderMap(){ + return headers; + } protected HashMap getCookieMap(){ return cookies; } diff --git a/src/zutil/net/http/HttpHeaderParser.java b/src/zutil/net/http/HttpHeaderParser.java index 5fc4a1c..c656ea9 100755 --- a/src/zutil/net/http/HttpHeaderParser.java +++ b/src/zutil/net/http/HttpHeaderParser.java @@ -29,6 +29,7 @@ import zutil.parser.URLDecoder; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; +import java.util.Map; import java.util.regex.Pattern; public class HttpHeaderParser { @@ -41,6 +42,7 @@ public class HttpHeaderParser { private BufferedReader in; + private boolean readStatusLine; /** @@ -50,6 +52,7 @@ public class HttpHeaderParser { */ public HttpHeaderParser(BufferedReader in){ this.in = in; + this.readStatusLine = true; } /** @@ -58,81 +61,98 @@ public class HttpHeaderParser { * @param in is the String */ public HttpHeaderParser(String in){ - this.in = new BufferedReader(new StringReader(in)); + this(new BufferedReader(new StringReader(in))); } public HttpHeader read() throws IOException { - HttpHeader header = null; + HttpHeader header = new HttpHeader(); String line = null; - if( (line=in.readLine()) != null && !line.isEmpty() ){ - header = new HttpHeader(); - parseStatusLine(header, line); - while( (line=in.readLine()) != null && !line.isEmpty() ){ - parseLine(header, line); - } - parseCookies(header); + + // First line + if (readStatusLine) { + if( (line=in.readLine()) != null && !line.isEmpty() ) + parseStatusLine(header, line); + else + return null; } + // Read header body + while( (line=in.readLine()) != null && !line.isEmpty() ){ + parseHeaderLine(header, line); + } + // Post processing + parseHeaderValue(header.getCookieMap(), header.getHeader(HEADER_COOKIE)); + return header; } + /** + * @param readStatusLine indicates if the stream contains http status lines. (default: true) + */ + public void setReadStatusLine(boolean readStatusLine){ + this.readStatusLine = readStatusLine; + } /** - * Parses the first header line and ads the values to - * the map and returns the file name and path - * - * @param line The header String - * @return The path and file name as a String + * Parses the first line of a http request/response and stores the values in a HttpHeader object + * + * @param header the header object where the cookies will be stored. + * @param statusLine the status line String */ - protected static void parseStatusLine(HttpHeader header, String line){ + public static void parseStatusLine(HttpHeader header, String statusLine){ // Server Response - if( line.startsWith("HTTP/") ){ + if( statusLine.startsWith("HTTP/") ){ header.setIsRequest(false); - header.setHTTPVersion( Float.parseFloat( line.substring( 5 , 8))); - header.setHTTPCode( Integer.parseInt( line.substring( 9, 12 ))); + header.setHTTPVersion( Float.parseFloat( statusLine.substring( 5 , 8))); + header.setHTTPCode( Integer.parseInt( statusLine.substring( 9, 12 ))); } // Client Request - else if(line.contains("HTTP/")){ + else if(statusLine.contains("HTTP/")){ header.setIsRequest(true); - header.setRequestType( line.substring(0, line.indexOf(" "))); - header.setHTTPVersion( Float.parseFloat( line.substring(line.lastIndexOf("HTTP/")+5 , line.length()).trim())); - line = (line.substring(header.getRequestType().length()+1, line.lastIndexOf("HTTP/"))); + header.setRequestType( statusLine.substring(0, statusLine.indexOf(" ")).trim() ); + header.setHTTPVersion( Float.parseFloat( statusLine.substring(statusLine.lastIndexOf("HTTP/")+5 , statusLine.length()).trim())); + statusLine = (statusLine.substring(header.getRequestType().length()+1, statusLine.lastIndexOf("HTTP/"))); // parse URL and attributes - int index = line.indexOf('?'); + int index = statusLine.indexOf('?'); if(index > -1){ - header.setRequestURL( line.substring(0, index)); - line = line.substring( index+1, line.length()); - parseURLParameters(header, line); + header.setRequestURL( statusLine.substring(0, index)); + statusLine = statusLine.substring( index+1, statusLine.length()); + parseURLParameters(header, statusLine); } else{ - header.setRequestURL(line); + header.setRequestURL(statusLine); } } } /** - * Parses the rest of the header + * Parses a http key value paired header line * + * @param header the header object where the cookies will be stored. * @param line is the next line in the header */ - protected void parseLine(HttpHeader header, String line){ + public static void parseHeaderLine(HttpHeader header, String line){ String[] data = PATTERN_COLON.split( line, 2 ); - header.putHeader( + header.getHeaderMap().put( data[0].trim().toUpperCase(), // Key (data.length>1 ? data[1] : "").trim()); //Value } /** - * Parses the header "Cookie" and stores all cookies in the HttpHeader object + * Parses a header value string that contains key and value paired data and + * stores them in a HashMap. If a pair only contain a key the the value + * will be set as a empty string. + * + * @param map the Map where the cookies will be stored. + * @param cookieHeader the raw cookie header String that will be parsed */ - protected void parseCookies(HttpHeader header){ - String cookieHeader = header.getHeader(HEADER_COOKIE); + public static void parseHeaderValue(Map map, String cookieHeader){ if(cookieHeader != null && !cookieHeader.isEmpty()){ String[] tmp = PATTERN_SEMICOLON.split(cookieHeader); for(String cookie : tmp){ String[] tmp2 = PATTERN_EQUAL.split(cookie, 2); - header.putCookie( + map.put( tmp2[0].trim(), // Key (tmp2.length>1 ? tmp2[1] : "").trim()); //Value } @@ -140,19 +160,19 @@ public class HttpHeaderParser { } /** - * Parses a String with variables from a get or post - * that was sent from a client - * - * @param attributes is the String containing all the attributes + * Parses a string with variables from a get or post request that was sent from a client + * + * @param header the header object where the cookies will be stored. + * @param urlAttributes is the String containing all the attributes */ - protected static void parseURLParameters(HttpHeader header, String attributes){ + public static void parseURLParameters(HttpHeader header, String urlAttributes){ String[] tmp; - attributes = URLDecoder.decode(attributes); + urlAttributes = URLDecoder.decode(urlAttributes); // get the variables - String[] data = PATTERN_AND.split( attributes ); + String[] data = PATTERN_AND.split( urlAttributes ); for(String element : data){ tmp = PATTERN_EQUAL.split(element, 2); - header.putURLAttribute( + header.getUrlAttributeMap().put( tmp[0].trim(), // Key (tmp.length>1 ? tmp[1] : "").trim()); //Value } diff --git a/src/zutil/net/http/HttpServer.java b/src/zutil/net/http/HttpServer.java index a92fa4a..60f60a2 100755 --- a/src/zutil/net/http/HttpServer.java +++ b/src/zutil/net/http/HttpServer.java @@ -194,7 +194,7 @@ public class HttpServer extends ThreadedTCPNetworkServer{ tmp.contains("text/xml") || tmp.contains("text/plain")) { // save the variables - header.putURLAttribute("", tmpBuff.toString()); + header.getUrlAttributeMap().put("", tmpBuff.toString()); } else if (tmp.contains("multipart/form-data")) { // TODO: File upload throw new UnsupportedOperationException("HTTP Content-Type 'multipart-form-data' not supported."); diff --git a/test/zutil/net/http/HTTPUploaderTest.java b/test/zutil/net/http/HTTPUploaderTest.java deleted file mode 100755 index 601957e..0000000 --- a/test/zutil/net/http/HTTPUploaderTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015 Ziver Koc - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package zutil.net.http; - -import java.io.IOException; -import java.util.Map; - - -public class HTTPUploaderTest implements HttpPage{ - - public static void main(String[] args) throws IOException{ - HttpServer server = new HttpServer(80); - server.setDefaultPage(new HTTPUploaderTest()); - server.run(); - } - - public void respond(HttpPrintStream out, - HttpHeader client_info, - Map session, - Map cookie, - Map request) throws IOException { - - if(!session.containsKey("file1")){ - out.println("" + - "
" + - "

Please specify a file, or a set of files:
" + - " " + - "

" + - " " + - "
" + - ""); - } - } - -} diff --git a/test/zutil/net/http/HTTPGuessTheNumber.java b/test/zutil/net/http/page/HTTPGuessTheNumber.java similarity index 93% rename from test/zutil/net/http/HTTPGuessTheNumber.java rename to test/zutil/net/http/page/HTTPGuessTheNumber.java index 2b509c6..97d482d 100755 --- a/test/zutil/net/http/HTTPGuessTheNumber.java +++ b/test/zutil/net/http/page/HTTPGuessTheNumber.java @@ -22,13 +22,18 @@ * THE SOFTWARE. */ -package zutil.net.http; +package zutil.net.http.page; + +import zutil.net.http.HttpHeader; +import zutil.net.http.HttpPage; +import zutil.net.http.HttpPrintStream; +import zutil.net.http.HttpServer; import java.io.IOException; import java.util.Map; -public class HTTPGuessTheNumber implements HttpPage{ +public class HTTPGuessTheNumber implements HttpPage { public static void main(String[] args) throws IOException{ //HttpServer server = new HttpServer("localhost", 443, FileFinder.find("keySSL"), "rootroot");//SSL