Refactored some things in the http package
This commit is contained in:
parent
e091a9abe6
commit
f77a757b6d
5 changed files with 74 additions and 112 deletions
|
|
@ -148,7 +148,7 @@ public class HttpHeader {
|
||||||
|
|
||||||
protected void setIsRequest(boolean request) { this.request = request; }
|
protected void setIsRequest(boolean request) { this.request = request; }
|
||||||
protected void setRequestType(String type){
|
protected void setRequestType(String type){
|
||||||
this.type = type.trim();
|
this.type = type;
|
||||||
}
|
}
|
||||||
protected void setHTTPVersion(float version){
|
protected void setHTTPVersion(float version){
|
||||||
this.version = version;
|
this.version = version;
|
||||||
|
|
@ -159,16 +159,10 @@ public class HttpHeader {
|
||||||
protected void setRequestURL(String url){
|
protected void setRequestURL(String url){
|
||||||
this.url = url.trim().replaceAll("//", "/");
|
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<String,String> getHeaderMap(){
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
protected HashMap<String,String> getCookieMap(){
|
protected HashMap<String,String> getCookieMap(){
|
||||||
return cookies;
|
return cookies;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import zutil.parser.URLDecoder;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class HttpHeaderParser {
|
public class HttpHeaderParser {
|
||||||
|
|
@ -41,6 +42,7 @@ public class HttpHeaderParser {
|
||||||
|
|
||||||
|
|
||||||
private BufferedReader in;
|
private BufferedReader in;
|
||||||
|
private boolean readStatusLine;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -50,6 +52,7 @@ public class HttpHeaderParser {
|
||||||
*/
|
*/
|
||||||
public HttpHeaderParser(BufferedReader in){
|
public HttpHeaderParser(BufferedReader in){
|
||||||
this.in = in;
|
this.in = in;
|
||||||
|
this.readStatusLine = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -58,81 +61,98 @@ public class HttpHeaderParser {
|
||||||
* @param in is the String
|
* @param in is the String
|
||||||
*/
|
*/
|
||||||
public HttpHeaderParser(String in){
|
public HttpHeaderParser(String in){
|
||||||
this.in = new BufferedReader(new StringReader(in));
|
this(new BufferedReader(new StringReader(in)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public HttpHeader read() throws IOException {
|
public HttpHeader read() throws IOException {
|
||||||
HttpHeader header = null;
|
HttpHeader header = new HttpHeader();
|
||||||
String line = null;
|
String line = null;
|
||||||
if( (line=in.readLine()) != null && !line.isEmpty() ){
|
|
||||||
header = new HttpHeader();
|
// First line
|
||||||
|
if (readStatusLine) {
|
||||||
|
if( (line=in.readLine()) != null && !line.isEmpty() )
|
||||||
parseStatusLine(header, line);
|
parseStatusLine(header, line);
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Read header body
|
||||||
while( (line=in.readLine()) != null && !line.isEmpty() ){
|
while( (line=in.readLine()) != null && !line.isEmpty() ){
|
||||||
parseLine(header, line);
|
parseHeaderLine(header, line);
|
||||||
}
|
|
||||||
parseCookies(header);
|
|
||||||
}
|
}
|
||||||
|
// Post processing
|
||||||
|
parseHeaderValue(header.getCookieMap(), header.getHeader(HEADER_COOKIE));
|
||||||
|
|
||||||
return header;
|
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
|
* Parses the first line of a http request/response and stores the values in a HttpHeader object
|
||||||
* the map and returns the file name and path
|
|
||||||
*
|
*
|
||||||
* @param line The header String
|
* @param header the header object where the cookies will be stored.
|
||||||
* @return The path and file name as a String
|
* @param statusLine the status line String
|
||||||
*/
|
*/
|
||||||
protected static void parseStatusLine(HttpHeader header, String line){
|
public static void parseStatusLine(HttpHeader header, String statusLine){
|
||||||
// Server Response
|
// Server Response
|
||||||
if( line.startsWith("HTTP/") ){
|
if( statusLine.startsWith("HTTP/") ){
|
||||||
header.setIsRequest(false);
|
header.setIsRequest(false);
|
||||||
header.setHTTPVersion( Float.parseFloat( line.substring( 5 , 8)));
|
header.setHTTPVersion( Float.parseFloat( statusLine.substring( 5 , 8)));
|
||||||
header.setHTTPCode( Integer.parseInt( line.substring( 9, 12 )));
|
header.setHTTPCode( Integer.parseInt( statusLine.substring( 9, 12 )));
|
||||||
}
|
}
|
||||||
// Client Request
|
// Client Request
|
||||||
else if(line.contains("HTTP/")){
|
else if(statusLine.contains("HTTP/")){
|
||||||
header.setIsRequest(true);
|
header.setIsRequest(true);
|
||||||
header.setRequestType( line.substring(0, line.indexOf(" ")));
|
header.setRequestType( statusLine.substring(0, statusLine.indexOf(" ")).trim() );
|
||||||
header.setHTTPVersion( Float.parseFloat( line.substring(line.lastIndexOf("HTTP/")+5 , line.length()).trim()));
|
header.setHTTPVersion( Float.parseFloat( statusLine.substring(statusLine.lastIndexOf("HTTP/")+5 , statusLine.length()).trim()));
|
||||||
line = (line.substring(header.getRequestType().length()+1, line.lastIndexOf("HTTP/")));
|
statusLine = (statusLine.substring(header.getRequestType().length()+1, statusLine.lastIndexOf("HTTP/")));
|
||||||
|
|
||||||
// parse URL and attributes
|
// parse URL and attributes
|
||||||
int index = line.indexOf('?');
|
int index = statusLine.indexOf('?');
|
||||||
if(index > -1){
|
if(index > -1){
|
||||||
header.setRequestURL( line.substring(0, index));
|
header.setRequestURL( statusLine.substring(0, index));
|
||||||
line = line.substring( index+1, line.length());
|
statusLine = statusLine.substring( index+1, statusLine.length());
|
||||||
parseURLParameters(header, line);
|
parseURLParameters(header, statusLine);
|
||||||
}
|
}
|
||||||
else{
|
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
|
* @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 );
|
String[] data = PATTERN_COLON.split( line, 2 );
|
||||||
header.putHeader(
|
header.getHeaderMap().put(
|
||||||
data[0].trim().toUpperCase(), // Key
|
data[0].trim().toUpperCase(), // Key
|
||||||
(data.length>1 ? data[1] : "").trim()); //Value
|
(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){
|
public static void parseHeaderValue(Map<String,String> map, String cookieHeader){
|
||||||
String cookieHeader = header.getHeader(HEADER_COOKIE);
|
|
||||||
if(cookieHeader != null && !cookieHeader.isEmpty()){
|
if(cookieHeader != null && !cookieHeader.isEmpty()){
|
||||||
String[] tmp = PATTERN_SEMICOLON.split(cookieHeader);
|
String[] tmp = PATTERN_SEMICOLON.split(cookieHeader);
|
||||||
for(String cookie : tmp){
|
for(String cookie : tmp){
|
||||||
String[] tmp2 = PATTERN_EQUAL.split(cookie, 2);
|
String[] tmp2 = PATTERN_EQUAL.split(cookie, 2);
|
||||||
header.putCookie(
|
map.put(
|
||||||
tmp2[0].trim(), // Key
|
tmp2[0].trim(), // Key
|
||||||
(tmp2.length>1 ? tmp2[1] : "").trim()); //Value
|
(tmp2.length>1 ? tmp2[1] : "").trim()); //Value
|
||||||
}
|
}
|
||||||
|
|
@ -140,19 +160,19 @@ public class HttpHeaderParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a String with variables from a get or post
|
* Parses a string with variables from a get or post request that was sent from a client
|
||||||
* that was sent from a client
|
|
||||||
*
|
*
|
||||||
* @param attributes is the String containing all the attributes
|
* @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;
|
String[] tmp;
|
||||||
attributes = URLDecoder.decode(attributes);
|
urlAttributes = URLDecoder.decode(urlAttributes);
|
||||||
// get the variables
|
// get the variables
|
||||||
String[] data = PATTERN_AND.split( attributes );
|
String[] data = PATTERN_AND.split( urlAttributes );
|
||||||
for(String element : data){
|
for(String element : data){
|
||||||
tmp = PATTERN_EQUAL.split(element, 2);
|
tmp = PATTERN_EQUAL.split(element, 2);
|
||||||
header.putURLAttribute(
|
header.getUrlAttributeMap().put(
|
||||||
tmp[0].trim(), // Key
|
tmp[0].trim(), // Key
|
||||||
(tmp.length>1 ? tmp[1] : "").trim()); //Value
|
(tmp.length>1 ? tmp[1] : "").trim()); //Value
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ public class HttpServer extends ThreadedTCPNetworkServer{
|
||||||
tmp.contains("text/xml") ||
|
tmp.contains("text/xml") ||
|
||||||
tmp.contains("text/plain")) {
|
tmp.contains("text/plain")) {
|
||||||
// save the variables
|
// save the variables
|
||||||
header.putURLAttribute("", tmpBuff.toString());
|
header.getUrlAttributeMap().put("", tmpBuff.toString());
|
||||||
} else if (tmp.contains("multipart/form-data")) {
|
} else if (tmp.contains("multipart/form-data")) {
|
||||||
// TODO: File upload
|
// TODO: File upload
|
||||||
throw new UnsupportedOperationException("HTTP Content-Type 'multipart-form-data' not supported.");
|
throw new UnsupportedOperationException("HTTP Content-Type 'multipart-form-data' not supported.");
|
||||||
|
|
|
||||||
|
|
@ -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<String, Object> session,
|
|
||||||
Map<String, String> cookie,
|
|
||||||
Map<String, String> request) throws IOException {
|
|
||||||
|
|
||||||
if(!session.containsKey("file1")){
|
|
||||||
out.println("</html>" +
|
|
||||||
" <form enctype='multipart/form-data' method='post'>" +
|
|
||||||
" <p>Please specify a file, or a set of files:<br>" +
|
|
||||||
" <input type='file' name='datafile' size='40'>" +
|
|
||||||
" </p>" +
|
|
||||||
" <input type='submit' value='Send'>" +
|
|
||||||
" </form>" +
|
|
||||||
"</html>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -22,7 +22,12 @@
|
||||||
* THE SOFTWARE.
|
* 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.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue