lol
This commit is contained in:
commit
613bef2496
108 changed files with 8397 additions and 0 deletions
28
src/zutil/network/http/HttpPage.java
Normal file
28
src/zutil/network/http/HttpPage.java
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package zutil.network.http;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This is a interface for a ordinary page for the HttpServer
|
||||
*
|
||||
* @author Ziver
|
||||
*
|
||||
*/
|
||||
public interface HttpPage{
|
||||
/**
|
||||
* This method has to be implemented for every page.
|
||||
* This method is called when a client wants a response
|
||||
* from this specific page.
|
||||
*
|
||||
* @param out The PrintStream to the client
|
||||
* @param client_info Information about the client
|
||||
* @param session Session values for the client
|
||||
* @param cookie Cookie information from the client
|
||||
* @param request POST and GET requests from the client
|
||||
*/
|
||||
public abstract void respond(HttpPrintStream out,
|
||||
HashMap<String,String> client_info,
|
||||
HashMap<String,String> session,
|
||||
HashMap<String,String> cookie,
|
||||
HashMap<String,String> request);
|
||||
}
|
||||
135
src/zutil/network/http/HttpPrintStream.java
Normal file
135
src/zutil/network/http/HttpPrintStream.java
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
package zutil.network.http;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This PrintStream is written for HTTP use
|
||||
* It has buffer capabilities and cookie management.
|
||||
*
|
||||
* @author Ziver
|
||||
*
|
||||
*/
|
||||
public class HttpPrintStream extends PrintStream{
|
||||
private HashMap<String, String> cookie;
|
||||
private StringBuffer buffer;
|
||||
private boolean buffer_enabled;
|
||||
|
||||
public HttpPrintStream(OutputStream out) {
|
||||
super(out);
|
||||
|
||||
cookie = new HashMap<String, String>();
|
||||
buffer = new StringBuffer();
|
||||
buffer_enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the buffering capability of the PrintStream.
|
||||
* Nothing will be sent to the client when buffering
|
||||
* is enabled until you close or flush the stream.
|
||||
*
|
||||
* @param b
|
||||
*/
|
||||
public void enableBuffering(boolean b){
|
||||
buffer_enabled = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a cookie that will be sent to the client
|
||||
*
|
||||
* @param key The name of the cookie
|
||||
* @param value The value of the cookie
|
||||
* @throws Exception Throws exception if the header has already been sent
|
||||
*/
|
||||
public void setCookie(String key, String value) throws Exception{
|
||||
if(cookie == null)
|
||||
throw new Exception("Header already sent!!!");
|
||||
cookie.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the given header directly to the client.
|
||||
* No buffering involved.
|
||||
*
|
||||
* @param header The header to send
|
||||
* @throws Exception Throws exception if the header has already been sent
|
||||
*/
|
||||
public void sendHeader(String header) throws Exception{
|
||||
if(cookie == null)
|
||||
throw new Exception("Header already sent!!!");
|
||||
super.println(header);
|
||||
}
|
||||
|
||||
/**
|
||||
* prints whit a new line
|
||||
*/
|
||||
public void println(String s){
|
||||
printOrBuffer(s+"\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* NOT TO BE USED!!!!
|
||||
* use printOrBuffer(String s) instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void print(String s){
|
||||
super.print(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* prints to all
|
||||
*/
|
||||
public void printOrBuffer(String s){
|
||||
if(buffer_enabled){
|
||||
buffer.append(s);
|
||||
}
|
||||
else{
|
||||
if(cookie != null){
|
||||
for(String key : cookie.keySet()){
|
||||
super.println("Set-Cookie: "+key+"="+cookie.get(key)+"; ");
|
||||
}
|
||||
super.println(" \n");
|
||||
cookie = null;
|
||||
}
|
||||
super.print(s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends out all the buffer and clears it
|
||||
*/
|
||||
public void flush(){
|
||||
if(buffer_enabled){
|
||||
buffer_enabled = false;
|
||||
printOrBuffer(buffer.toString());
|
||||
buffer.delete(0, buffer.length());
|
||||
buffer_enabled = true;
|
||||
}
|
||||
super.flush();
|
||||
}
|
||||
|
||||
public void close(){
|
||||
flush();
|
||||
super.close();
|
||||
}
|
||||
|
||||
public void println(){ println("");}
|
||||
public void println(boolean x){ println(""+x);}
|
||||
public void println(char x){ println(""+x);}
|
||||
public void println(char[] x){ println(new String(x));}
|
||||
public void println(double x){ println(""+x);}
|
||||
public void println(float x){ println(""+x);}
|
||||
public void println(int x){ println(""+x);}
|
||||
public void println(long x){ println(""+x);}
|
||||
public void println(Object x){ println(""+x);}
|
||||
|
||||
public void print(boolean x){ printOrBuffer(""+x);}
|
||||
public void print(char x){ printOrBuffer(""+x);}
|
||||
public void print(char[] x){ printOrBuffer(new String(x));}
|
||||
public void print(double x){ printOrBuffer(""+x);}
|
||||
public void print(float x){ printOrBuffer(""+x);}
|
||||
public void print(int x){ printOrBuffer(""+x);}
|
||||
public void print(long x){ printOrBuffer(""+x);}
|
||||
public void print(Object x){ printOrBuffer(""+x);}
|
||||
}
|
||||
282
src/zutil/network/http/HttpServer.java
Normal file
282
src/zutil/network/http/HttpServer.java
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
package zutil.network.http;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
|
||||
import zutil.MultiPrintStream;
|
||||
|
||||
/**
|
||||
* A simple web server that handles both cookies and
|
||||
* sessions for all the clients
|
||||
*
|
||||
* @author Ziver
|
||||
* TODO: File upload
|
||||
*/
|
||||
public class HttpServer extends Thread{
|
||||
public static final boolean DEBUG = false;
|
||||
public static final String SERVER_VERSION = "Evil HttpServer 1.0";
|
||||
public static final int COOKIE_TTL = 200;
|
||||
public static final int SESSION_TTL = 200;
|
||||
|
||||
public final String server_url;
|
||||
public final int server_port;
|
||||
|
||||
private HashMap<String,HttpPage> pages;
|
||||
private HttpPage defaultPage;
|
||||
private HashMap<String,HashMap<String,String>> sessions;
|
||||
private int nextSessionId;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the sever
|
||||
*
|
||||
* @param url The address to the server
|
||||
* @param port The port that the server should listen to
|
||||
*/
|
||||
public HttpServer(String url, int port){
|
||||
this.server_url = url;
|
||||
this.server_port = port;
|
||||
|
||||
pages = new HashMap<String,HttpPage>();
|
||||
sessions = new HashMap<String,HashMap<String,String>>();
|
||||
nextSessionId = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a HttpPage to a specific URL
|
||||
*
|
||||
* @param name The URL or name of the page
|
||||
* @param page The page itself
|
||||
*/
|
||||
public void setPage(String name, HttpPage page){
|
||||
pages.put(name, page);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a default page that will be shown
|
||||
* if there is no other matching page,
|
||||
*
|
||||
* @param page The HttpPage that will be shown
|
||||
*/
|
||||
public void setDefaultPage(HttpPage page){
|
||||
defaultPage = page;
|
||||
}
|
||||
|
||||
public void run(){
|
||||
try{
|
||||
ServerSocket ss = new ServerSocket(server_port);
|
||||
MultiPrintStream.out.println("Http Server Running!!!");
|
||||
|
||||
while(true){
|
||||
new HttpServerThread(ss.accept());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal class that handles all the requests
|
||||
*
|
||||
* @author Ziver
|
||||
*
|
||||
*/
|
||||
class HttpServerThread extends Thread{
|
||||
private HttpPrintStream out;
|
||||
private BufferedReader in;
|
||||
private Socket socket;
|
||||
|
||||
public HttpServerThread(Socket socket) throws IOException{
|
||||
out = new HttpPrintStream(socket.getOutputStream());
|
||||
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
this.socket = socket;
|
||||
start();
|
||||
if(DEBUG)MultiPrintStream.out.println("New Connection!!! "+socket.getInetAddress().getHostName());
|
||||
}
|
||||
|
||||
public void run(){
|
||||
String tmp = null;
|
||||
int tmpi;
|
||||
|
||||
String page_url = "";
|
||||
HashMap<String,String> client_info = new HashMap<String,String>();
|
||||
HashMap<String,String> cookie = new HashMap<String,String>();
|
||||
HashMap<String,String> request = new HashMap<String,String>();
|
||||
|
||||
//**************************** REQUEST *********************************
|
||||
try {
|
||||
if(DEBUG)MultiPrintStream.out.println("Reciving Http Request!!!");
|
||||
while(!(tmp=in.readLine()).isEmpty()){
|
||||
//System.err.println(tmp);
|
||||
//*********** Handling Get variables
|
||||
if(tmp.startsWith("GET")){
|
||||
// Gets the file URL and get values
|
||||
tmp = (tmp.substring(5, tmp.indexOf("HTTP/"))).trim();
|
||||
page_url = parseHttpHeader(tmp, request);
|
||||
}
|
||||
//********* Handling Post variable data
|
||||
else if(tmp.startsWith("POST")){
|
||||
// Gets the file URL and get values
|
||||
tmp = (tmp.substring(6, tmp.indexOf("HTTP/"))).trim();
|
||||
page_url = parseHttpHeader(tmp, request);
|
||||
}
|
||||
//********* Handling Cookies
|
||||
else if(tmp.startsWith("Cookie")){
|
||||
tmp = tmp.substring(tmp.indexOf(':')+1, tmp.length());
|
||||
while(!tmp.isEmpty()){
|
||||
tmpi = ( (tmpi = tmp.indexOf(';')) == -1 ? tmp.length() : tmpi);
|
||||
cookie.put(
|
||||
(tmp.substring(0, tmp.indexOf('=')).trim() ), // Key
|
||||
(tmp.substring(tmp.indexOf('=')+1, tmpi)).trim() ); //Value
|
||||
if(tmp.indexOf(';') > 0)
|
||||
tmp = tmp.substring(tmp.indexOf(';')+1, tmp.length());
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
//********* Handling Client info
|
||||
else{
|
||||
if(tmp.indexOf(':') > -1){
|
||||
client_info.put(
|
||||
(tmp.substring(0, tmp.indexOf(':')).trim() ), // Key
|
||||
(tmp.substring(tmp.indexOf(':')+1, tmp.length())).trim() ); //Value
|
||||
}
|
||||
else{
|
||||
MultiPrintStream.out.println("Faild to parsse header: "+tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//******* Read in the post data if available
|
||||
if(client_info.containsKey("Content-Length")){
|
||||
// Reads the post data size
|
||||
tmp = client_info.get("Content-Length");
|
||||
int post_data_length = Integer.parseInt(
|
||||
tmp.substring(tmp.indexOf(':')+1, tmp.length()).trim() );
|
||||
|
||||
if(client_info.get("Content-Type").equals("application/x-www-form-urlencoded")){
|
||||
StringBuffer tmpb = new StringBuffer();
|
||||
// read the data
|
||||
for(int i=0; i<post_data_length ;i++){
|
||||
tmpb.append((char)in.read());
|
||||
}
|
||||
// get the variables
|
||||
parseVariables(tmpb.toString(), request);
|
||||
}
|
||||
else if(client_info.get("Content-Type").contains("multipart/form-data")){
|
||||
// TODO:
|
||||
throw new Exception("\"multipart/form-data\" Not implemented!!!");
|
||||
}
|
||||
}
|
||||
//*****************
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
out.sendHeader("HTTP/1.0 500 ERROR");
|
||||
} catch (Exception e1) {}
|
||||
out.println("500 Internal Error(Header: "+tmp+"): "+e.getMessage());
|
||||
}
|
||||
try {
|
||||
//**************************** HANDLE REQUEST *********************************
|
||||
// Get the client session or create one
|
||||
HashMap<String,String> client_session;
|
||||
if(cookie.containsKey("session_id") && sessions.containsKey(cookie.get("session_id"))){
|
||||
client_session = sessions.get(cookie.get("session_id"));
|
||||
}
|
||||
else{
|
||||
client_session = new HashMap<String,String>();
|
||||
client_session.put("session_id", ""+nextSessionId);
|
||||
sessions.put(""+nextSessionId, client_session);
|
||||
nextSessionId++;
|
||||
}
|
||||
// Debug
|
||||
if(DEBUG){
|
||||
MultiPrintStream.out.println("# page_url: "+page_url);
|
||||
MultiPrintStream.out.println("# cookie: "+cookie);
|
||||
MultiPrintStream.out.println("# client_session: "+client_session);
|
||||
MultiPrintStream.out.println("# client_info: "+client_info);
|
||||
MultiPrintStream.out.println("# request: "+request);
|
||||
}
|
||||
//**************************** RESPONSE ************************************
|
||||
if(DEBUG)MultiPrintStream.out.println("Sending Http Response!!!");
|
||||
out.sendHeader("HTTP/1.0 200 OK");
|
||||
out.sendHeader("Server: "+SERVER_VERSION);
|
||||
out.sendHeader("Content-Type: text/html");
|
||||
out.setCookie("session_id", client_session.get("session_id"));
|
||||
|
||||
|
||||
if(!page_url.isEmpty() && pages.containsKey(page_url)){
|
||||
pages.get(page_url).respond(out, client_info, client_session, cookie, request);
|
||||
}
|
||||
else if(defaultPage != null){
|
||||
defaultPage.respond(out, client_info, client_session, cookie, request);
|
||||
}
|
||||
else{
|
||||
out.println("404 ERROR");
|
||||
}
|
||||
|
||||
//********************************************************************************
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
out.println("500 Internal Error: "+e.getMessage());
|
||||
}
|
||||
|
||||
try{
|
||||
if(DEBUG)MultiPrintStream.out.println("Conection Closed!!!");
|
||||
out.close();
|
||||
in.close();
|
||||
socket.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the first header line and ads the values to
|
||||
* the map and returns the file name and path
|
||||
*
|
||||
* @param header The header String
|
||||
* @param map The HashMap to put the variables to
|
||||
* @return The path and file name as a String
|
||||
*/
|
||||
private String parseHttpHeader(String header, HashMap<String, String> map){
|
||||
String page_url = "";
|
||||
// cut out the page name
|
||||
if(header.indexOf('?') > -1){
|
||||
page_url = header.substring(0, header.indexOf('?'));
|
||||
header = header.substring(header.indexOf('?')+1, header.length());
|
||||
parseVariables(header, map);
|
||||
}
|
||||
else{
|
||||
page_url = header;
|
||||
}
|
||||
|
||||
return page_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a String with variables from a get or post
|
||||
* from a client and puts the data into a HashMap
|
||||
*
|
||||
* @param header A String with all the variables
|
||||
* @param map The HashMap to put all the variables into
|
||||
*/
|
||||
private void parseVariables(String header, HashMap<String, String> map){
|
||||
int tmpi;
|
||||
// get the variables
|
||||
while(!header.isEmpty()){
|
||||
tmpi = ( (tmpi = header.indexOf('&')) == -1 ? header.length() : tmpi);
|
||||
map.put(
|
||||
(header.substring(0, header.indexOf('=')).trim() ), // Key
|
||||
(header.substring(header.indexOf('=')+1, tmpi )).trim() ); //Value
|
||||
if(header.indexOf('&') > 0)
|
||||
header = header.substring(header.indexOf('&')+1, header.length());
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue