import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.*;
public class HttpProtocol {
PrintWriter out= null;
BufferedReader in= null;
private Socket MySocket;
OutputStream outputstream=null;
File webRootDirector=null;
long contLength;
byte[] contL;
/*public OutputStream getOutputStream() {
return outputstream;
}*/
public HttpProtocol (Socket MySocket, BufferedReader in,PrintWriter out){
this.in=in;
this.out=out;
this.MySocket=MySocket;
}
public void processInput(){
// InputStream streamin= mySocket.getInputStream();
// if (streamin==null) return;
//BufferedReader in=new BufferedReader(new InputStreamReader(streamin));
try{
StringTokenizer tok=new StringTokenizer(in.readLine());
if (!tok.hasMoreTokens())
respond(HTTP_BADREQUEST,"Wrong Syntax.Try :GET /foo/doublefoo/foo.html");
String method =tok.nextToken();
if (!tok.hasMoreTokens())
respond(HTTP_BADREQUEST,"Wrong Syntax.No URI defined.Try :GET /foo/doublefoo/foo.html");
String Uri = decodeUri1(tok.nextToken());
Properties parameter =new Properties();
int erotimatiko=Uri.indexOf('?');
if(erotimatiko>=0){
decodeUri2(Uri.substring(erotimatiko+1),parameter);
Uri = decodeUri1(Uri.substring(0,erotimatiko));
}
Properties header=new Properties();
if(tok.hasMoreTokens())
{
String epomgram=in.readLine();
while(epomgram.trim().length()>0){
int anwkatw=epomgram.indexOf(':');
header.put(epomgram.substring(0,anwkatw).trim(),epomgram.substring(anwkatw+1).trim());
epomgram=in.readLine();
}
}
if(method.equalsIgnoreCase("POST"))
decodeUri2(in.readLine(),parameter);
if(!method.equalsIgnoreCase("POST")&& !method.equalsIgnoreCase("GET"))
respond(HTTP_BADREQUEST,"Bad Request:we only support GET or POST methods");
Response resp=serving(Uri,method,header,parameter);
if(resp==null)
respond (HTTP_INTERNALERROR,"An Internal Server Error has occured: server returned a null response");
else{System.out.println(resp.status);
System.out.println(resp.mimeType);
System.out.println(resp.data);
sendResponse(resp.status,resp.mimeType,resp.header,resp.data);
//in.close();
}//// prosekse pou einai to try .elekse kala ta { }
}catch(IOException e){
try{
respond(HTTP_INTERNALERROR, "SERVER INTERNAL ERROR: IOException: " + e.getMessage());
}catch ( Throwable t ) {}
}
catch ( InterruptedException ie )
{ }
} //problima me parentheseis
private void respond( String status, String msg ) throws InterruptedException
{
sendResponse( status, MIME_PLAINTEXT, null, new ByteArrayInputStream( msg.getBytes()));
throw new InterruptedException();
}
private void sendResponse(String status,String mime,Properties header,InputStream data){
try {
// OutputStream out= mySocket.getOutputStream();
// PrintWriter print=new PrintWriter(out);
//pws tha to paroume apo th my server thread ayto.. opws kai to in
// OutputStream eee=setOutputStream(os);
System.out.println("HTTP/1.1 "+status+"\r\n");
out.print("HTTP/1.1 "+status+"\r\n");//allakseee toooo
out.print("Content-Type: " + mime + "\r\n");
if(header==null || header.getProperty("Date")==null)
out.print("Date:"+gmtFrmt.format(new Date())+"\r\n");
if(header!=null){
Enumeration e =header.keys();
while(e.hasMoreElements()){
String key=(String)e.nextElement();
String value =header.getProperty(key);
out.print(key+":"+value+"\r\n");
}
}
out.print("r\n");
out.flush();
if(data!=null){
// byte[] buffer=new byte[2048];
while(true){
int read =data.read(contL,0,(int)contLength);
if (read<=0)
break;
//OutputStream mprizola=new BufferedOutputStream(MySocket.getOutputStream());
(MySocket.getOutputStream()).write(contL,0,read);
}
}
(MySocket.getOutputStream()).flush();
(MySocket.getOutputStream()).close();
//if(data!=null)
//data.close();
}
catch (IOException ioe){
try{
MySocket.close();
}catch(Throwable t){}
}
}
/* //if not perl
File f = new File(httpRootDir,requestedFile);//dimiourgia arxeiou me orismata ton trexonta
// katalogo kai to antistoixo arxeio zitisis
byte[] theData = new byte[(int) f.length( )];//dimourgia pinaka byte me megethos
//to megethos tou arxeiou zitisis
z=theData.length;//mikos tou pinaka aparaitito gia to HEADER
if (f.canRead()==false)//diabasma arxeiou : anepitixes
void sendFile(byte[] theData,File f)
{
//sinaritisi aposotilis tou arxeiou pou zitithike apo ton client
try
{
DataInputStream fista = new DataInputStream(new BufferedInputStream(
new FileInputStream(f)));
OutputStream raw = new BufferedOutputStream(client.getOutputStream( ));
sendResponseHeader(contentType);//stelnei to aparaitito header ston client
fista.readFully(theData);
//diabazei ton pinaka byte pou iparxei sti sinartisi diadikasia_arxeiou
fista.close();
raw.write(theData);//stelnei ta dedomena tou pinaka
raw.flush();
}
catch(IOException e)
{
System.out.println("error sending");
}
}
*/
private String decodeUri1(String string) throws InterruptedException{
try {
StringBuffer buff=new StringBuffer();
for(int i=0;i<string.length();i++){
char c=string.charAt(i);
switch (c){
case '+':
buff.append(' ');
break;
case '%':
buff.append((char)Integer.parseInt(string.substring(i+1,i+3),16));
i=i+2;
break;
default:
buff.append(c);
break;
}
}return new String(buff.toString().getBytes());
}
catch(Exception e){
respond(HTTP_BADREQUEST,"BAD REQUEST:Problem with uri encoding");
return null;
}
}
private void decodeUri2(String param,Properties p) throws InterruptedException{
if (param==null) return;
StringTokenizer str=new StringTokenizer(param,"&");
while(str.hasMoreTokens()){
String next=str.nextToken();
int ison=next.indexOf('=');
if(ison>=0)
p.put(decodeUri1(next.substring(0,ison)).trim(),decodeUri1(next.substring(ison+1)));
}
}
public Response serving (String Uri,String method,Properties header,Properties parameter){
//gia na blepoume ki emeis ti ginetai
System.out.println(method+" "+Uri);
Enumeration enume=header.propertyNames();
while(enume.hasMoreElements()){
String mtbl=(String)enume.nextElement();
System.out.println("header :"+mtbl+" = "+header.getProperty(mtbl)+"\n");}
enume=parameter.propertyNames();
while(enume.hasMoreElements()){
String mtbl=(String)enume.nextElement();
System.out.println("header :"+mtbl+" = "+parameter.getProperty(mtbl)+"\n");}
return sendingNow(Uri,header,new File("."));
}
public Response sendingNow(String Uri,Properties header,File webRootDirect){
//prwtos elegxos an ontws yparxei to arxiko directory
if(!webRootDirect.isDirectory()){return new Response(HTTP_INTERNALERROR,MIME_PLAINTEXT,"Internal Error :given webRootDirectory is not a directory");}
//katharizoume ligo to uri gia na broume to path sthn poria enw orizoume gia fileseparator to "/"
Uri=Uri.trim().replace(File.separatorChar,'/');
if (Uri.indexOf('?')>=0){Uri=Uri.substring(0,Uri.indexOf('?'));}
//prosexoume na mhn eksipiretoume ../ uri pou bgainoun apo to root tou webserver mas
if(Uri.startsWith("..")||Uri.indexOf( "../" ) >= 0)
return new Response(HTTP_FORBIDDEN,MIME_PLAINTEXT,"Server doesn't allow <..> characters");
File f = new File( webRootDirect, Uri ); //ftiaxnoume ena path xrisimopoiwntas to url
if (!f.exists())
return new Response(HTTP_NOTFOUND,MIME_PLAINTEXT,"Error 404 file not found.");
//koitame an yparxei to file mas
if (f.isDirectory()){
//koitame an yparxei to index.html h to index.htm se periptwsh pou mas exdei dwthei mono to directory
if (new File(f,"index.html").exists())
f=new File(webRootDirect,Uri+"index.html");//prosthetoume me ayton ton tropo sto uri to index.html kai ayto to kanoume
//path mesw ths file to opoio elegxoume an yparxei ontws.to idio kai gia tin index.htm
else if (new File(f,"index.htm").exists())
f=new File(webRootDirect,Uri+"index.htm");
//an den yparxei index file kanoume list to directory se morfi html
else {
String[] arxeia_ola=f.list();
String msg ="<html><body><h1>Directory " + Uri + "</h1><br/>";
if(Uri.length()>1){
String path=Uri.substring(0,Uri.length()-1); //bgazoume to teleytaio "/"
int slas=path.lastIndexOf('/');
if (slas>=0 && slas<path.length()) // an twra yparxei slas sto uri kai h thesi tou einai kapoios deiktis mikroteros apo to mhkos
msg+="<b><a href=\"" + Uri.substring(0, slas+1) + "\">..</a></b><br/>"; // ftiaxnoume to link gia ton prohgoumeno fakelo
}
for (int i=0; i<arxeia_ola.length;i++){
File thisfile=new File(f,arxeia_ola[i]);
if(thisfile.isDirectory()){
arxeia_ola[i]+="/" ;// bazoume ena slas stous fakelous gia na ksexwrizoun
}
msg+="<a href=\"" + URLEncoder.encode( Uri + arxeia_ola[i]) + "\">" +
arxeia_ola[i] + "</a>"; // to kanoume encode gia na leitourgisei san link gia to ekastote arxeio
}
return new Response(HTTP_OK,MIME_HTML,msg);
}
}
String mime=null;
int tel=Uri.lastIndexOf('.');
if (tel<0||tel>Uri.length())
mime=MIME_DEFAULT_BINARY;
if (tel>=0)
mime=(String)getMimeTypes.get(Uri.substring(tel+1).toLowerCase());
try{
FileInputStream file=new FileInputStream(f);
contL=new byte[(int) f.length()];
contLength=contL.length;
System.out.println(contLength);
String stringlenth=String.valueOf(contLength);
System.out.println(stringlenth);
Response resp= new Response(HTTP_OK,mime,file);
resp.putHeader("Content-length",stringlenth);//""+ f.length());
// resp1.header.put("Content-length",""+ f.length());
System.out.println(contLength);
return resp;
}catch (IOException e){
return new Response(HTTP_FORBIDDEN, MIME_PLAINTEXT, "FORBIDDEN: failed to serve the requested file." );
}
}
private static Hashtable getMimeTypes = new Hashtable();
static
{
StringTokenizer st = new StringTokenizer(
"htm text/html "+
"html text/html "+
"txt text/plain "+
"asc text/plain "+
"gif image/gif "+
"jpg image/jpeg "+
"jpeg image/jpeg "+
"png image/png "+
"mp3 audio/mpeg "+
"m3u audio/mpeg-url " +
"pdf application/pdf "+
"doc application/msword "+
"ogg application/x-ogg "+
"zip application/octet-stream "+
"exe application/octet-stream "+
"class application/octet-stream " );
while ( st.hasMoreTokens())
getMimeTypes.put( st.nextToken(), st.nextToken());
}
private static java.text.SimpleDateFormat gmtFrmt;
static
{
gmtFrmt = new java.text.SimpleDateFormat( "E, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
gmtFrmt.setTimeZone(TimeZone.getTimeZone("GMT"));
}
public static final String
HTTP_OK = "200 OK",
HTTP_REDIRECT = "301 Moved Permanently",
HTTP_FORBIDDEN = "403 Forbidden",
HTTP_NOTFOUND = "404 Not Found",
HTTP_BADREQUEST = "400 Bad Request",
HTTP_INTERNALERROR = "500 Internal Server Error",
HTTP_NOTIMPLEMENTED = "501 Not Implemented";
public static final String
MIME_PLAINTEXT = "text/plain",
MIME_HTML = "text/html",
MIME_DEFAULT_BINARY = "application/octet-stream";
}
class Response{
String HTTP_OK = "200 OK";
public String status; // meta thn antistoixish twn dynatwn timwn se metabliti p.x 200 OK
public String mimeType; // edw apothikeyoume times opws to "text/plain"
public InputStream data;
public Properties header;// arxikopoioume edw gia na ftiaksoume methodo prosthesis ki allwn timwn sthn header
//kataskeyastes
public Response(){this.status=HTTP_OK;}//gia data kai mime null
public Response(String status,String mimeType,InputStream data){
this.status=status;
this.mimeType=mimeType;
this.data=data;}
public Response(String status,String mimeType,String message){
this.status=status;
this.mimeType=mimeType;
this.data=new ByteArrayInputStream(message.getBytes());}
//xrhsimopoioume mia methodo gia na mporoume na prosthetoume ston hashtable headers
public void putHeader(String mtbl,String value){
header.put( mtbl, value);
}
}