From 3f9b5437884279b7165c05dd9de130fd16050cbb Mon Sep 17 00:00:00 2001 From: bdemsky Date: Tue, 6 Nov 2007 05:36:20 +0000 Subject: [PATCH] *** empty log message *** --- .../Java/Jhttpp2ClientInputStream.java | 336 +++++++++++++++++ .../Jhttpp2/Java/Jhttpp2HTTPSession.java | 349 ++++++++++++++++++ .../Jhttpp2/Java/Jhttpp2Launcher.java | 31 ++ .../Benchmarks/Jhttpp2/Java/Jhttpp2Read.java | 58 +++ .../Jhttpp2/Java/Jhttpp2Server.java | 323 ++++++++++++++++ .../Java/Jhttpp2ServerInputStream.java | 21 ++ .../Jhttpp2/Java/Jhttpp2URLMatch.java | 41 ++ .../Benchmarks/Jhttpp2/Java/Jhttpp2Utils.java | 67 ++++ .../Benchmarks/Jhttpp2/Java/OnURLAction.java | 81 ++++ .../Jhttpp2/Java/WildcardDictionary.java | 182 +++++++++ 10 files changed, 1489 insertions(+) create mode 100755 Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2ClientInputStream.java create mode 100644 Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2HTTPSession.java create mode 100755 Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Launcher.java create mode 100755 Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Read.java create mode 100755 Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Server.java create mode 100755 Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2ServerInputStream.java create mode 100755 Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2URLMatch.java create mode 100755 Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Utils.java create mode 100755 Robust/src/Benchmarks/Jhttpp2/Java/OnURLAction.java create mode 100755 Robust/src/Benchmarks/Jhttpp2/Java/WildcardDictionary.java diff --git a/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2ClientInputStream.java b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2ClientInputStream.java new file mode 100755 index 00000000..10562fd4 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2ClientInputStream.java @@ -0,0 +1,336 @@ +/* Written and copyright 2001-2003 Benjamin Kohl. + * Distributed under the GNU General Public License; see the README file. + * This code comes with NO WARRANTY. + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.BufferedInputStream; +import java.net.InetAddress; +import java.net.UnknownHostException; + + +/** + File: Jhttpp2BufferedFilterStream.java + @author Benjamin Kohl +*/ +public class Jhttpp2ClientInputStream extends BufferedInputStream { + private boolean filter; + private String buf; + private int lread; + /** + * The length of the header (with body, if one) + */ + private int header_length; + /** + * The length of the (optional) body of the actual request + */ + private int content_len; + /** + * This is set to true with requests with bodies, like "POST" + */ + private boolean body; + private static Jhttpp2Server server; + private Jhttpp2HTTPSession connection; + private InetAddress remote_host; + private String remote_host_name; + private String errordescription; + private int statuscode; + + public String url; + public String method; + public int remote_port; + public int post_data_len; + public boolean ssl; + + public int getHeaderLength() { + return header_length; + } + + public InetAddress getRemoteHost() { return remote_host; } + public String getRemoteHostName() { return remote_host_name; } + + private void init() { + lread = 0; + header_length = 0; + content_len = 0; + ssl = false; + body = false; + remote_port = 0; + post_data_len = 0; + } + + public Jhttpp2ClientInputStream(Jhttpp2Server server,Jhttpp2HTTPSession connection,InputStream a) { + super(a); + init(); + this.server = server; + this.connection=connection; + } + /** + * Handler for the actual HTTP request + * @exception IOException + */ + public int read(byte[] a) { + statuscode = connection.SC_OK; + if (ssl) return super.read(a); + boolean cookies_enabled=server.enableCookiesByDefault(); + String rq=""; + header_length=0; + post_data_len = 0; + content_len = 0; + boolean start_line=true; + buf = getLine(); // reads the first line + + boolean cnt=true; + while (lread>2&&cnt) { + if (start_line) { + start_line = false; + int methodID = server.getHttpMethod(buf); + if (methodID==-1) { + statuscode = connection.SC_NOT_SUPPORTED; + } else { + if (methodID==2) { + ssl = true; + } + InetAddress host = parseRequest(buf,methodID); + + if (statuscode == connection.SC_OK) { + if (!server.use_proxy && !ssl) { + /* creates a new request without the hostname */ + buf = method + " " + url + " " + server.getHttpVersion() + "\r\n"; + lread = buf.length(); + } + if ((server.use_proxy && connection.notConnected()) || !host.equals(remote_host)) { + if (server.debug) server.writeLog("read_f: STATE_CONNECT_TO_NEW_HOST"); + statuscode = connection.SC_CONNECTING_TO_HOST; + remote_host = host; + } + /* ------------------------- + * url blocking (only "GET" method) + * -------------------------*/ + if (server.block_urls && methodID==0 && statuscode!=connection.SC_FILE_REQUEST) { + if (server.debug) System.printString("Searching match..."); + Jhttpp2URLMatch match=server.findMatch(this.remote_host_name+url); + if (match!=null){ + if (server.debug) System.printString("Match found!"); + cookies_enabled=match.getCookiesEnabled(); + if (match.getActionIndex()==-1) cnt=false; else { + OnURLAction action=(OnURLAction)server.getURLActions().elementAt(match.getActionIndex()); + if (action.onAccesssDeny()) { + statuscode=connection.SC_URL_BLOCKED; + if (action.onAccessDenyWithCustomText()) errordescription=action.getCustomErrorText(); + } else if (action.onAccessRedirect()) { + statuscode=connection.SC_MOVED_PERMANENTLY; + errordescription=action.newLocation(); + } + } + }//end if match!=null) + } //end if (server.block... + } + } + } else { // end if(startline) + /*----------------------------------------------- + * Content-Length parsing + *-----------------------------------------------*/ + if(server.startsWith(buf.toUpperCase(),"CONTENT-LENGTH")) { + String clen=buf.substring(16); + if (clen.indexOf("\r")!=-1) clen=clen.substring(0,clen.indexOf("\r")); + else if(clen.indexOf("\n")!=-1) clen=clen.substring(0,clen.indexOf("\n")); + content_len=Integer.parseInt(clen); + if (server.debug) server.writeLog("read_f: content_len: " + content_len); + if (!ssl) body=true; // Note: in HTTP/1.1 any method can have a body, not only "POST" + } + else if (server.startsWith(buf,"Proxy-Connection:")) { + if (!server.use_proxy) buf=null; + else { + buf="Proxy-Connection: Keep-Alive\r\n"; + lread=buf.length(); + } + } + /*----------------------------------------------- + * cookie crunch section + *-----------------------------------------------*/ + else if(server.startsWith(buf,"Cookie:")) { + if (!cookies_enabled) buf=null; + } + /*------------------------------------------------ + * Http-Header filtering section + *------------------------------------------------*/ + else if (server.filter_http) { + if(server.startsWith(buf,"Referer:")) {// removes "Referer" + buf=null; + } else if(server.startsWith(buf,"User-Agent")) // changes User-Agent + { + buf="User-Agent: " + server.getUserAgent() + "\r\n"; + lread=buf.length(); + } + } + } + if (buf!=null) { + rq+=buf; + if (server.debug) server.writeLog(buf); + header_length+=lread; + } + buf=getLine(); + } + rq+=buf; //adds last line (should be an empty line) to the header String + header_length+=lread; + + if (header_length==0) { + if (server.debug) server.writeLog("header_length=0, setting status to SC_CONNECTION_CLOSED (buggy request)"); + statuscode=connection.SC_CONNECTION_CLOSED; + } + + for (int i=0;i + * Sets up the URL, method and remote hostname. + * @return an InetAddress for the hostname, null on errors with a statuscode!=SC_OK + */ + public InetAddress parseRequest(String a,int method_index) { + if (server.debug) + server.writeLog(a); + String f; + int pos; + url=""; + if (ssl) { + f = a.substring(8); + } else { + method = a.substring(0,a.indexOf(" ")); //first word in the line + pos = a.indexOf(":"); // locate first : + if (pos == -1) { // occours with "GET / HTTP/1.1" + url = a.substring(a.indexOf(" ")+1,a.lastIndexOf(" ")); + if (method_index == 0) { // method_index==0 --> GET + if (url.indexOf(server.WEB_CONFIG_FILE) != -1) { + statuscode = connection.SC_CONFIG_RQ; + } else { + statuscode = connection.SC_FILE_REQUEST; + } + } else { + if (method_index == 1 && url.indexOf(server.WEB_CONFIG_FILE) != -1) { // allow "POST" for admin log in + statuscode = connection.SC_CONFIG_RQ; + } else { + statuscode=connection.SC_INTERNAL_SERVER_ERROR; + errordescription="This WWW proxy supports only the \"GET\" method while acting as webserver."; + } + } + return null; + } + f = a.substring(pos+3); //removes "http://" + } + pos=f.indexOf(" "); // locate space, should be the space before "HTTP/1.1" + if (pos==-1) { // buggy request + statuscode=connection.SC_CLIENT_ERROR; + errordescription="Your browser sent an invalid request: \""+ a + "\""; + return null; + } + f = f.substring(0,pos); //removes all after space + // if the url contains a space... it's not our mistake...(url's must never contain a space character) + pos=f.indexOf("/"); // locate the first slash + if (pos!=-1) { + url=f.substring(pos); // saves path without hostname + f=f.substring(0,pos); // reduce string to the hostname + } + else url="/"; // occurs with this request: "GET http://localhost HTTP/1.1" + pos = f.indexOf(":"); // check for the portnumber + if (pos!=-1) { + String l_port =f.substring(pos+1); + if (l_port.indexOf(" ")!=-1) + l_port=l_port.substring(0,l_port.indexOf(" ")); + int i_port=80; + //BCD + i_port = Integer.parseInt(l_port); + f = f.substring(0,pos); + remote_port=i_port; + } else + remote_port = 80; + remote_host_name = f; + InetAddress address = null; + if (server.log_access) + server.logAccess(method + " " + getFullURL()); + + address = InetAddress.getByName(f); + + if (remote_port == server.port && address.equals(InetAddress.getLocalHost())) { + if (url.indexOf(server.WEB_CONFIG_FILE) != -1 && (method_index == 0 || method_index == 1)) + statuscode = connection.SC_CONFIG_RQ; + else if (method_index > 0 ) { + statuscode=connection.SC_INTERNAL_SERVER_ERROR; + errordescription="This WWW proxy supports only the \"GET\" method while acting as webserver."; + } else + statuscode = connection.SC_FILE_REQUEST; + } + return address; + } + /** + * @return boolean whether the actual connection was established with the CONNECT method. + * @since 0.2.21 + */ + public boolean isTunnel() { + return ssl; + } + /** + * @return the full qualified URL of the actual request. + * @since 0.4.0 + */ + public String getFullURL() { + String sh=""; + if (ssl) + sh="s"; + if (remote_port!=80) + return "http" + sh + "://" + getRemoteHostName() + + ":" + remote_port + url; + else + return "http" + sh + "://" + getRemoteHostName() + + url; + } + /** + * @return status-code for the actual request + * @since 0.3.5 + */ + public int getStatusCode() + { + return statuscode; + } + /** + * @return the (optional) error-description for this request + */ + public String getErrorDescription() + { + return errordescription; + } +} diff --git a/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2HTTPSession.java b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2HTTPSession.java new file mode 100644 index 00000000..5dde6bcf --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2HTTPSession.java @@ -0,0 +1,349 @@ +/* Written and copyright 2001-2003 Benjamin Kohl. + * Distributed under the GNU General Public License; see the README file. + * This code comes with NO WARRANTY. + */ + +import java.net.Socket; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import java.io.BufferedOutputStream; +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.File; +import java.io.FileInputStream; + + +/** + One HTTP connection + @file Jhttpp2HTTPSession.java + @author Benjamin Kohl +*/ +public class Jhttpp2HTTPSession extends Thread { + + public final int SC_OK; + public final int SC_CONNECTING_TO_HOST; + public final int SC_HOST_NOT_FOUND; + public final int SC_URL_BLOCKED; + public final int SC_CLIENT_ERROR; + public final int SC_INTERNAL_SERVER_ERROR; + public final int SC_NOT_SUPPORTED; + public final int SC_REMOTE_DEBUG_MODE; + public final int SC_CONNECTION_CLOSED; + public final int SC_HTTP_OPTIONS_THIS; + public final int SC_FILE_REQUEST; + public final int SC_MOVED_PERMANENTLY; + public final int SC_CONFIG_RQ; + + + void init() { + SC_OK=0; + SC_CONNECTING_TO_HOST=1; + SC_HOST_NOT_FOUND=2; + SC_URL_BLOCKED=3; + SC_CLIENT_ERROR=4; + SC_INTERNAL_SERVER_ERROR=5; + SC_NOT_SUPPORTED=6; + SC_REMOTE_DEBUG_MODE=7; + SC_CONNECTION_CLOSED=8; + SC_HTTP_OPTIONS_THIS=9; + SC_FILE_REQUEST=10; + SC_MOVED_PERMANENTLY=11; + SC_CONFIG_RQ = 12; + } + + private Jhttpp2Server server; + + /** downstream connections */ + private Socket client; + private BufferedOutputStream out; + private Jhttpp2ClientInputStream in; + + /** upstream connections */ + private Socket HTTP_Socket; + private BufferedOutputStream HTTP_out; + private Jhttpp2ServerInputStream HTTP_in; + + public Jhttpp2HTTPSession(Jhttpp2Server server,Socket client) { + init(); + in = new Jhttpp2ClientInputStream(server,this,client.getInputStream());//,true); + out = new BufferedOutputStream(client.getOutputStream()); + this.server=server; + this.client=client; + start(); + } + public Socket getLocalSocket() { + return client; + } + public Socket getRemoteSocket() { + return HTTP_Socket; + } + public boolean isTunnel() { + return in.isTunnel(); + } + public boolean notConnected() { + return HTTP_Socket==null; + } + public void sendHeader(int a,boolean b) { + sendHeader(a); + endHeader(); + out.flush(); + } + public void sendHeader(int status, String content_type, long content_length) { + sendHeader(status); + sendLine("Content-Length", String.valueOf(content_length)); + sendLine("Content-Type", content_type ); + } + public void sendLine(String s) { + write(out,s + "\r\n"); + } + public void sendLine(String header, String s) { + write(out,header + ": " + s + "\r\n"); + } + public void endHeader() { + write(out,"\r\n"); + } + public void run() { + if (server.debug)server.writeLog("begin http session"); + server.increaseNumConnections(); + handleRequest(); + in.close(); // since 0.4.10b + out.close(); + client.close(); + // close upstream connections (webserver or other proxy) + if (!notConnected()) { + HTTP_Socket.close(); + HTTP_out.close(); + HTTP_in.close(); + } + server.decreaseNumConnections(); + if (server.debug)server.writeLog("end http session"); + } + /** sends a message to the user */ + public void sendErrorMSG(int a,String info) { + String statuscode = sendHeader(a); + String localhost = "localhost"+":"+server.port; + String msg = "\r" + + "\r" + + "" + statuscode + "\r" + + "\r" // use css style sheet in htdocs + + "\r" + + "

HTTP " + statuscode + "

\r" + + "
\r" + + "

Your request for the following URL failed:

" + + "

" + in.getFullURL() + "

\r" + + "

Reason: " + info + "

" + + "
\r" + + "

jHTTPp2 HTTP Proxy, Version " + server.getServerVersion() + " at " + localhost + + "
Copyright © 2001-2003 Benjamin Kohl

\r" + + "

jHTTPp2 local website Configuration

" + + ""; + sendLine("Content-Length",String.valueOf(msg.length())); + sendLine("Content-Type","text/html; charset=iso-8859-1"); + endHeader(); + write(out,msg); + out.flush(); + } + + public String sendHeader(int a) { + String stat; + if (a==200) + stat="200 OK"; + else if (a==202) + stat="202 Accepted"; + else if (a==300) + stat="300 Ambiguous"; + else if (a==301) + stat="301 Moved Permanently"; + else if (a==400) + stat="400 Bad Request"; + else if (a==401) + stat="401 Denied"; + else if (a==403) + stat="403 Forbidden"; + else if (a==404) + stat="404 Not Found"; + else if (a==405) + stat="405 Bad Method"; + else if (a==413) + stat="413 Request Entity Too Large"; + else if (a==415) + stat="415 Unsupported Media"; + else if (a==501) + stat="501 Not Implemented"; + else if (a==502) + stat="502 Bad Gateway"; + else if (a==504) + stat="504 Gateway Timeout"; + else if (a==505) + stat="505 HTTP Version Not Supported"; + else + stat="500 Internal Server Error"; + sendLine(server.getHttpVersion() + " " + stat); + sendLine("Server",server.getServerIdentification()); + if (a==501) + sendLine("Allow","GET, HEAD, POST, PUT, DELETE, CONNECT"); + sendLine("Cache-Control", "no-cache, must-revalidate"); + sendLine("Connection","close"); + return stat; + } + + /** the main routine, where it all happens */ + public void handleRequest() { + InetAddress remote_host; + Jhttpp2Read remote_in=null; + int remote_port; + byte[] b=new byte[65536]; + int numread=in.read(b); + boolean cnt=true; + while(cnt) { // with this loop we support persistent connections + if (numread==-1) { // -1 signals an error + if (in.getStatusCode()!=SC_CONNECTING_TO_HOST) { + int code=in.getStatusCode(); + if (code==SC_CONNECTION_CLOSED) { + } else if (code==SC_CLIENT_ERROR) { + sendErrorMSG(400,"Your client sent a request that this proxy could not understand. (" + in.getErrorDescription() + ")"); + } else if (code==SC_HOST_NOT_FOUND) + sendErrorMSG(504,"Host not found.
jHTTPp2 was unable to resolve the hostname of this request.
Perhaps the hostname was misspelled, the server is down or you have no connection to the internet."); + else if (code==SC_INTERNAL_SERVER_ERROR) + sendErrorMSG(500,"Server Error! (" + in.getErrorDescription() + ")"); + else if (code==SC_NOT_SUPPORTED) + sendErrorMSG(501,"Your client used a HTTP method that this proxy doesn't support: (" + in.getErrorDescription() + ")"); + else if (code==SC_URL_BLOCKED) { + if (in.getErrorDescription()!=null && in.getErrorDescription().length()>0) + sendErrorMSG(403,in.getErrorDescription()); + else + sendErrorMSG(403,"The request for this URL was denied by the jHTTPp2 URL-Filter."); + } else if (code==SC_HTTP_OPTIONS_THIS) { + sendHeader(200); endHeader(); + } else if (code==SC_FILE_REQUEST) + file_handler(); + else if (code==SC_CONFIG_RQ) + admin_handler(b); + //case SC_HTTP_TRACE: + else if (code==SC_MOVED_PERMANENTLY) { + sendHeader(301); + write(out,"Location: " + in.getErrorDescription() + "\r\n"); + endHeader(); + out.flush(); + } + cnt=false;// return from main loop. + } else { // also an error because we are not connected (or to the wrong host) + // Creates a new connection to a remote host. + if (!notConnected()) { + HTTP_Socket.close(); + } + numread=in.getHeaderLength(); // get the header length + if (!server.use_proxy) {// sets up hostname and port + remote_host=in.getRemoteHost(); + remote_port=in.remote_port; + } else { + remote_host=server.proxy; + remote_port=server.proxy_port; + } + connect(remote_host,remote_port); + if (!in.isTunnel() || (in.isTunnel() && server.use_proxy)) + { // no SSL-Tunnel or SSL-Tunnel with another remote proxy: simply forward the request + HTTP_out.write(b, 0, numread); + HTTP_out.flush(); + } + else + { // SSL-Tunnel with "CONNECT": creates a tunnel connection with the server + sendLine(server.getHttpVersion() + " 200 Connection established"); + sendLine("Proxy-Agent",server.getServerIdentification()); + endHeader(); out.flush(); + } + remote_in = new Jhttpp2Read(server,this, HTTP_in, out); // reads data from the remote server + server.addBytesWritten(numread); + } + } + if (cnt) { + while(cnt) { // reads data from the client + numread=in.read(b); + if (numread!=-1) { + HTTP_out.write(b, 0, numread); + HTTP_out.flush(); + server.addBytesWritten(numread); + } else cnt=false; + } // end of inner loop + cnt=true; + } + }// end of main loop + out.flush(); + if (!notConnected() && remote_in != null) + remote_in.close(); // close Jhttpp2Read thread + return; + } + /** connects to the given host and port */ + public void connect(InetAddress host,int port) { + HTTP_Socket = new Socket(host,port); + HTTP_in = new Jhttpp2ServerInputStream(server,this,HTTP_Socket.getInputStream(),false); + HTTP_out = new BufferedOutputStream(HTTP_Socket.getOutputStream()); + } + /** converts an String into a Byte-Array to write it with the OutputStream */ + public void write(BufferedOutputStream o,String p) { + o.write(p.getBytes(),0,p.length()); + } + + /** + * Small webserver for local files in {app}/htdocs + * @since 0.4.04 + */ + public void file_handler() { + if (!server.www_server) { + sendErrorMSG(500, "The jHTTPp2 built-in WWW server module is disabled."); + return; + } + String filename=in.url; + if (filename.equals("/")) filename="index.html"; // convert / to index.html + else if (filename.startsWith("/")) filename=filename.substring(1); + if (filename.endsWith("/")) filename+="index.html"; // add index.html, if ending with / + File file = new File("htdocs/" + filename); // access only files in "htdocs" + if (true// !file.exists() || !file.canRead() // be sure that we can read the file + || filename.indexOf("..")!=-1 // don't allow ".." !!! + // || file.isDirectory() +) { // dont't read if it's a directory + sendErrorMSG(404,"The requested file /" + filename + " was not found or the path is invalid."); + return; + } + int pos = filename.lastIndexOf("."); // MIME type of the specified file + String content_type="text/plain"; // all unknown content types will be marked as text/plain + if (pos != -1) { + String extension = filename.substring(pos+1); + if (extension.equalsIgnoreCase("htm") || (extension.equalsIgnoreCase("html"))) content_type="text/html; charset=iso-8859-1"; + else if (extension.equalsIgnoreCase("jpg") || (extension.equalsIgnoreCase("jpeg"))) content_type="image/jpeg"; + else if (extension.equalsIgnoreCase("gif")) content_type = "image/gif"; + else if (extension.equalsIgnoreCase("png")) content_type = "image/png"; + else if (extension.equalsIgnoreCase("css")) content_type = "text/css"; + else if (extension.equalsIgnoreCase("pdf")) content_type = "application/pdf"; + else if (extension.equalsIgnoreCase("ps") || extension.equalsIgnoreCase("eps")) content_type = "application/postscript"; + else if (extension.equalsIgnoreCase("xml")) content_type = "text/xml"; + } + sendHeader(200,content_type, file.length() ); + endHeader(); + BufferedInputStream file_in = new BufferedInputStream(new FileInputStream(file)); + byte[] buffer=new byte[4096]; + int a=file_in.read(buffer); + while (a!=-1) { // read until EOF + out.write(buffer,0,a); + a = file_in.read(buffer); + } + out.flush(); + file_in.close(); // finished! + } + /** + * @since 0.4.10b + */ + public int getStatus() + { + return in.getStatusCode(); + } + /** + * @since 0.4.20a + * admin webpage + */ + public void admin_handler(byte[] b) { + } +} + diff --git a/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Launcher.java b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Launcher.java new file mode 100755 index 00000000..9d468596 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Launcher.java @@ -0,0 +1,31 @@ +/* Written and copyright 2001-2003 Benjamin Kohl. + * Distributed under the GNU General Public License; see the README file. + * This code comes with NO WARRANTY. + */ + +//import java.awt.Dimension; +//import java.awt.Toolkit; +//import javax.swing.UIManager; + +//import Jhttpp2MainFrame; +/** + * Title: jHTTPp2: Java HTTP Filter Proxy + * Description: starts thwe Swing GUI or the console-mode only proxy + * Copyright: Copyright (c) 2001-2003 + * + * @author Benjamin Kohl + */ + +public class Jhttpp2Launcher { + + public static void main(String[] args) { + Jhttpp2Server server = new Jhttpp2Server(true); + if (server.error) { + System.printString("Error: " + server.error_msg); + } + else { + server.start(); + System.printString("Running on port " + server.port+"\n"); + } + } +} diff --git a/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Read.java b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Read.java new file mode 100755 index 00000000..567c53f4 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Read.java @@ -0,0 +1,58 @@ +/* Written and copyright 2001-2003 Benjamin Kohl. + * Distributed under the GNU General Public License; see the README file. + * This code comes with NO WARRANTY. + */ + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +/** + File: Jhttpp2Read.java + reads from a Jhttpp2ClientInputStream and writes to the BufferedOutputStream + + @author Benjamin Kohl +*/ +public class Jhttpp2Read extends Thread +{ + private final int BUFFER_SIZE; + private BufferedInputStream in; + private BufferedOutputStream out; + private Jhttpp2HTTPSession connection; + private Jhttpp2Server server; + + public Jhttpp2Read(Jhttpp2Server server,Jhttpp2HTTPSession connection,BufferedInputStream l_in, BufferedOutputStream l_out) { + BUFFER_SIZE=96000; + in=l_in; + out=l_out; + this.connection=connection; + this.server=server; + start(); + } + public void run() { + read(); + } + private void read() { + int bytes_read=0; + byte[] buf=new byte[BUFFER_SIZE]; + boolean cnt=true; + while(cnt) { + bytes_read=in.read(buf); + if (bytes_read!=-1) { + out.write(buf,0,bytes_read); + out.flush(); + server.addBytesRead(bytes_read); + } else cnt=false; + } + if (connection.getStatus()!=connection.SC_CONNECTING_TO_HOST) // *uaaahhh*: fixes a very strange bug + connection.getLocalSocket().close(); + // why? If we are connecting to a new host (and this thread is already running!) , the upstream + // socket will be closed. So we get here and close our own downstream socket..... and the browser + // displays an empty page because jhttpp2 + // closes the connection..... so close the downstream socket only when NOT connecting to a new host.... + } + public void close() { + in.close(); + } +} + + diff --git a/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Server.java b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Server.java new file mode 100755 index 00000000..40b3566f --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Server.java @@ -0,0 +1,323 @@ +/* Written and copyright 2001-2003 Benjamin Kohl. + * Distributed under the GNU General Public License; see the README file. + * This code comes with NO WARRANTY. + * More Information and documentation: HTTP://jhttp2.sourceforge.net/ + */ + +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.net.InetAddress; +import java.net.BindException; + +import java.io.*; + +import java.util.Vector; +import java.util.Date; + +public class Jhttpp2Server extends Thread +{ + private static final String CRLF; + private final String VERSION; + private final String V_SPECIAL; + private final String HTTP_VERSION; + private final String MAIN_LOGFILE; + + private final String DATA_FILE; + private final String SERVER_PROPERTIES_FILE; + + private String http_useragent; + private ServerSocket listen; + private BufferedWriter logfile; + private BufferedWriter access_logfile; + private long bytesread; + private long byteswritten; + private int numconnections; + + private boolean enable_cookies_by_default; + private WildcardDictionary dic; + private Vector urlactions; + + public final int DEFAULT_SERVER_PORT; + public final String WEB_CONFIG_FILE; + + public int port; + public InetAddress proxy; + public int proxy_port; + + public long config_auth; + public long config_session_id; + public String config_user; + public String config_password; + + public static boolean error; + public static String error_msg; + + public boolean use_proxy; + public boolean block_urls; + public boolean filter_http; + public boolean debug; + public boolean log_access; + public String log_access_filename; + public boolean webconfig; + public boolean www_server; + + + public initvars() { + CRLF="\r\n"; + VERSION = "0.4.62"; + V_SPECIAL = " 2003-05-20"; + HTTP_VERSION = "HTTP/1.1"; + MAIN_LOGFILE = "server.log"; + DATA_FILE = "server.data"; + SERVER_PROPERTIES_FILE = "server.properties"; + http_useragent = "Mozilla/4.0 (compatible; MSIE 4.0; WindowsNT 5.0)"; + enable_cookies_by_default=true; + dic = new WildcardDictionary(); + urlactions = new Vector(); + DEFAULT_SERVER_PORT = 8088; + WEB_CONFIG_FILE = "admin/jp2-config"; + port = DEFAULT_SERVER_PORT; + proxy_port = 0; + config_auth = 0; + config_session_id = 0; + config_user = "root"; + config_password = "geheim"; + use_proxy=false; + block_urls=false; + filter_http=false; + debug=false; + log_access = true; + log_access_filename="paccess.log"; + webconfig = true; + www_server = true; +} + + void init() + { + if(log_access) { + access_logfile=new BufferedWriter(new FileWriter(log_access_filename,true)); + } + + logfile=new BufferedWriter(new FileWriter(MAIN_LOGFILE,true)); + writeLog("server startup..."); + + listen = new ServerSocket(port); + + if (error) { + writeLog(error_msg); + return; + } + } + public Jhttpp2Server() { + initvars(); + init(); + } + public Jhttpp2Server(boolean b) + { + initvars(); + System.printString("jHTTPp2 HTTP Proxy Server Release " + getServerVersion() + "\r\n" + +"Copyright (c) 2001-2003 Benjamin Kohl \r\n" + +"This software comes with ABSOLUTELY NO WARRANTY OF ANY KIND.\r\n" + +"http://jhttp2.sourceforge.net/\n"); + init(); + } + /** calls init(), sets up the serverport and starts for each connection + * new Jhttpp2Connection + */ + void serve() + { + writeLog("Server running."); + while(true) + { + Socket client = listen.accept(); + new Jhttpp2HTTPSession(this,client); + } + } + public void run() + { + serve(); + } + public void setErrorMsg(String a) + { + error=true; + error_msg=a; + } + /** + * Tests what method is used with the reqest + * @return -1 if the server doesn't support the method + */ + public int getHttpMethod(String d) + { + if (startsWith(d,"GET") || startsWith(d,"HEAD")) return 0; + if (startsWith(d,"POST") || startsWith(d,"PUT")) return 1; + if (startsWith(d,"CONNECT")) return 2; + if (startsWith(d,"OPTIONS")) return 3; + + return -1;/* No match... + + Following methods are not implemented: + || startsWith(d,"TRACE") */ + } + public boolean startsWith(String a,String what) + { + int l=what.length(); + int l2=a.length(); + if (l2>l) + return a.substring(0,l).equals(what); + else + return false; + } + /** + *@return the Server response-header field + */ + public String getServerIdentification() + { + return "jHTTPp2/" + getServerVersion(); + } + public String getServerVersion() + { + return VERSION + V_SPECIAL; + } + /** + * saves all settings with a ObjectOutputStream into a file + * @since 0.2.10 + */ + /** restores all Jhttpp2 options from "settings.dat" + * @since 0.2.10 + */ + /** + * @return the HTTP version used by jHTTPp2 + */ + public String getHttpVersion() + { + return HTTP_VERSION; + } + /** the User-Agent header field + * @since 0.2.17 + * @return User-Agent String + */ + public String getUserAgent() + { + return http_useragent; + } + public void setUserAgent(String ua) + { + http_useragent=ua; + } + /** + * writes into the server log file and adds a new line + * @since 0.2.21 + */ + public void writeLog(String s) + { + writeLog(s,true); + } + /** writes to the server log file + * @since 0.2.21 + */ + public void writeLog(String s,boolean b) + { + s=new Date().toString() + " " + s; + logfile.write(s,0,s.length()); + if (b) logfile.newLine(); + logfile.flush(); + if (debug)System.printString(s); + } + + public void closeLog() + { + writeLog("Server shutdown."); + logfile.flush(); + logfile.close(); + access_logfile.close(); + } + + public void addBytesRead(long read) + { + bytesread+=read; + } + /** + * Functions for the jHTTPp2 statistics: + * How many connections + * Bytes read/written + * @since 0.3.0 + */ + public void addBytesWritten(int written) + { + byteswritten+=written; + } + public int getServerConnections() + { + return numconnections; + } + public long getBytesRead() + { + return bytesread; + } + public long getBytesWritten() + { + return byteswritten; + } + public void increaseNumConnections() + { + numconnections++; + } + public void decreaseNumConnections() + { + numconnections--; + } + public void AuthenticateUser(String u,String p) { + if (config_user.equals(u) && config_password.equals(p)) { + config_auth = 1; + } else config_auth = 0; + } + public String getGMTString() + { + return new Date().toString(); + } + public Jhttpp2URLMatch findMatch(String url) + { + return (Jhttpp2URLMatch)dic.get(url); + } + public WildcardDictionary getWildcardDictionary() + { + return dic; + } + public Vector getURLActions() + { + return urlactions; + } + public boolean enableCookiesByDefault() + { + return this.enable_cookies_by_default; + } + public void enableCookiesByDefault(boolean a) + { + enable_cookies_by_default=a; + } + public void resetStat() + { + bytesread=0; + byteswritten=0; + } + /** + * @since 0.4.10a + */ + /** + * @since 0.4.10a + */ + /** + * @since 0.4.10a + */ + public void logAccess(String s) + { + access_logfile.write("[" + new Date().toString() + "] " + s + "\r\n"); + access_logfile.flush(); + } + public void shutdownServer() { + closeLog(); + System.exit(0); + } + +} diff --git a/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2ServerInputStream.java b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2ServerInputStream.java new file mode 100755 index 00000000..03470824 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2ServerInputStream.java @@ -0,0 +1,21 @@ +/* Written and copyright 2001 Benjamin Kohl. + * Distributed under the GNU General Public License; see the README file. + * This code comes with NO WARRANTY. + */ + +import java.io.BufferedInputStream; +import java.io.InputStream; +import java.io.IOException; + +public class Jhttpp2ServerInputStream extends BufferedInputStream { + private Jhttpp2HTTPSession connection; + + public Jhttpp2ServerInputStream(Jhttpp2Server server,Jhttpp2HTTPSession connection,InputStream a,boolean filter) { + super(a); + this.connection=connection; + } + public int read_f(byte[] b) { + return read(b); + } +} + diff --git a/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2URLMatch.java b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2URLMatch.java new file mode 100755 index 00000000..e37533c4 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2URLMatch.java @@ -0,0 +1,41 @@ +/** + * Title: jHTTPp2: Java HTTP Filter Proxy + * Copyright: Copyright (c) 2001-2003 Benjamin Kohl + * @author Benjamin Kohl + * @version 0.2.8 + */ + +public class Jhttpp2URLMatch { + String match; + String desc; + boolean cookies_enabled; + int actionindex; + + public Jhttpp2URLMatch(String match,boolean cookies_enabled,int actionindex,String description) + { + this.match=match; + this.cookies_enabled=cookies_enabled; + this.actionindex=actionindex; + this.desc=description; + } + public String getMatch() + { + return match; + } + public boolean getCookiesEnabled() + { + return cookies_enabled; + } + public int getActionIndex() + { + return actionindex; + } + public String getDescription() + { + return desc; + } + public String toString() + { + return "\"" + match + "\" " + desc; + } +} diff --git a/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Utils.java b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Utils.java new file mode 100755 index 00000000..baa7228e --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/Java/Jhttpp2Utils.java @@ -0,0 +1,67 @@ + + +/** + * Title: jHTTPp2: Java HTTP Filter Proxy + * Description: static utility routines + * Copyright: Copyright (c) 2001 Benjamin Kohl + + * @author Benjamin Kohl + * @version 0.4.22a + */ + +public class Jhttpp2Utils +{ + + +// +// Copyright (C)1996,1998 by Jef Poskanzer . All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +// SUCH DAMAGE. +// +// Visit the ACME Labs Java page for up-to-date versions of this and other +// fine Java utilities: http://www.acme.com/java/ + + /// URLDecoder to go along with java.net.URLEncoder. Why there isn't + // already a decoder in the standard library is a mystery to me. + public static String urlDecoder( String encoded ) + { + StringBuffer decoded = new StringBuffer(); + int len = encoded.length(); + for ( int i = 0; i < len; ++i ) + { + if ( encoded.charAt( i ) == '%' && i + 2 < len ) + { + int d1 = Character.digit( encoded.charAt( i + 1 ), 16 ); + int d2 = Character.digit( encoded.charAt( i + 2 ), 16 ); + if ( d1 != -1 && d2 != -1 ) + decoded.append( (char) ( ( d1 << 4 ) + d2 ) ); + i += 2; + } + else if ( encoded.charAt( i ) == '+' ) + decoded.append( ' ' ); + else + decoded.append( encoded.charAt( i ) ); + } + return decoded.toString(); + } + +} \ No newline at end of file diff --git a/Robust/src/Benchmarks/Jhttpp2/Java/OnURLAction.java b/Robust/src/Benchmarks/Jhttpp2/Java/OnURLAction.java new file mode 100755 index 00000000..01915587 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/Java/OnURLAction.java @@ -0,0 +1,81 @@ +/* Written and copyright 2001 Benjamin Kohl. + * Distributed under the GNU General Public License; see the README file. + * This code comes with NO WARRANTY. + * + * Title: jHTTPp2: Java HTTP Filter Proxy + * Description: An OpenSource HTTP Proxy + * Copyright: Copyright (c) 2001 Benjamin Kohl + * @author Benjamin Kohl + */ + +public class OnURLAction { + + private String customerrortext, desc, httppath, newlocation; + private boolean log,block,customtext,http_rq,anotherlocation; + public OnURLAction(String desc) + { + this.desc=desc; + } + public void denyAccess(String customerrortext) + { + this.block=true; + this.customtext=true; + this.customerrortext=customerrortext; + } + public void denyAccess() + { + block=true; + } + public void logAccess() + { + log=true; + } + public void anotherLocation(String newlocation) + { + this.anotherlocation=true; + this.newlocation=newlocation; + } + + public boolean onAccesssDeny() + { + return block; + } + public boolean onAccessLog() + { + return log; + } + public boolean onAccessDenyWithCustomText() + { + return customtext; + } + public boolean onAccessSendHTTPRequest() + { + return http_rq; + } + public boolean onAccessRedirect() + { + return this.anotherlocation; + } + public String newLocation() + { + return this.newlocation; + } + public void setHTTPAction(boolean http_rq, String httppath) + { + this.http_rq=http_rq; + this.httppath=httppath; + } + public String getCustomErrorText() + { + return customerrortext; + } + public String getDescription() + { + return desc; + } + public String toString() + { + return desc; + } + +} diff --git a/Robust/src/Benchmarks/Jhttpp2/Java/WildcardDictionary.java b/Robust/src/Benchmarks/Jhttpp2/Java/WildcardDictionary.java new file mode 100755 index 00000000..9d8bab67 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/Java/WildcardDictionary.java @@ -0,0 +1,182 @@ +// WildcardDictionary - a dictionary with wildcard lookups +// +// Copyright (C) 1996 by Jef Poskanzer . All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +// SUCH DAMAGE. +// +// Visit the ACME Labs Java page for up-to-date versions of this and other +// fine Java utilities: http://www.acme.com/java/ + +// package Acme; + +import java.util.*; + +/// A dictionary with wildcard lookups. +//

+// The keys in this dictionary are wildcard patterns. When you do a get(), +// the string you pass in is matched against all the patterns, and the +// first match is returned. +//

+// The wildcard matcher is fairly simple, it implements * meaning any +// string, ? meaning any single character, and | separating multiple +// patterns. All other characters must match literally. +//

+// Fetch the software.
+// Fetch the entire Acme package. +//

+// @see Acme.Utils#match + +public class WildcardDictionary extends Dictionary { + + private Vector keys; + private Vector elements; + + /// Constructor. + public WildcardDictionary() { + keys = new Vector(); + elements = new Vector(); + } + + /// Returns the number of elements contained within the dictionary. + public int size() { + return elements.size(); + } + + /// Returns true if the dictionary contains no elements. + public boolean isEmpty() { + return size() == 0; + } + + /// Returns an enumeration of the dictionary's keys. + public Enumeration keys() { + return keys.elements(); + } + + /// Returns an enumeration of the elements. Use the Enumeration methods + // on the returned object to fetch the elements sequentially. + public Enumeration elements() { + return elements.elements(); + } + + /// Gets the object associated with the specified key in the dictionary. + // The key is assumed to be a String, which is matched against + // the wildcard-pattern keys in the dictionary. + // @param key the string to match + // @returns the element for the key, or null if there's no match + // @see Acme.Utils#match + public synchronized Object get( Object key ) + { + String sKey = (String) key; + for ( int i = 0; i < keys.size(); ++i ) + { + String thisKey = (String) keys.elementAt( i ); + if ( match( thisKey, sKey ) ) + return elements.elementAt( i ); + } + return null; + } + + /// Puts the specified element into the Dictionary, using the specified + // key. The element may be retrieved by doing a get() with the same + // key. The key and the element cannot be null. + // @param key the specified wildcard-pattern key + // @param value the specified element + // @return the old value of the key, or null if it did not have one. + // @exception NullPointerException If the value of the specified + // element is null. + public synchronized Object put( Object key, Object element ) + { + int i = keys.indexOf( key ); + if ( i != -1 ) + { + Object oldElement = elements.elementAt( i ); + elements.setElementAt( element, i ); + return oldElement; + } + else + { + keys.addElement( key ); + elements.addElement( element ); + return null; + } + } + + /// Removes the element corresponding to the key. Does nothing if the + // key is not present. + // @param key the key that needs to be removed + // @return the value of key, or null if the key was not found. + public synchronized Object remove( Object key ) + { + int i = keys.indexOf( key ); + if ( i != -1 ) + { + Object oldElement = elements.elementAt( i ); + keys.removeElementAt( i ); + elements.removeElementAt( i ); + return oldElement; + } + else + return null; + } + + /** Checks whether a string matches a given wildcard pattern. + * Only does ? and *, and multiple patterns separated by |. + */ + public static boolean match( String pattern, String string ) { + for ( int p = 0; true; ++p ) { + boolean cnt=true; + for ( int s = 0; cnt; ++p, ++s ) { + boolean sEnd = ( s >= string.length() ); + boolean pEnd = ( p >= pattern.length() || + pattern.charAt( p ) == '|' ); + if ( sEnd && pEnd ) + return true; + if ( sEnd || pEnd ) + cnt=false; + else if ( pattern.charAt( p ) != '?' ) { + if ( pattern.charAt( p ) == '*' ) { + int i; + ++p; + for ( i = string.length(); i >= s; --i ) + if ( match( + pattern.substring( p ), + string.substring( i ) ) ) /* not quite right */ + return true; + cnt=false; + } + if ( pattern.charAt( p ) != string.charAt( s ) ) + cnt=false; + } + } + p = pattern.indexOf( '|', p ); + if ( p == -1 ) + return false; + } + } + /** + * Deletes all elements and keys. + */ + public void removeAllElements() { + elements.clear(); + keys.clear(); + } +} -- 2.34.1