package com.sleepless.net.http;
import java.net.*;
import java.io.*;
import java.util.*;
public class HTTPDaemon extends Thread
{
// These can be useful for simulating a slow server.
// 200 and 100 would probably simulate a 28Kbps connection
// 200 and 50 would probably simulate a 56Kbps connection
// A good set of values for normally operations would be 20000 and 0
// Of course this is just on my PII 400 sony vaio laptop.
// Other engines will probably vary.
static final int BUF_SIZE = 20000;
static final int DELAY = 0;
void m(String s){System.out.println(getClass().getName()+": "+s);}
int port;
public HTTPDaemon(int p)
{
port = p;
}
public void run()
{
try
{
m("Listening on port "+port);
ServerSocket ss = new ServerSocket(port);
while(true)
{
try
{
socket = ss.accept();
startTransaction();
}
catch(IOException e)
{
m(e.getMessage());
}
}
}
catch(IOException e)
{
e.printStackTrace();
}
System.exit(1);
}
BufferedReader br;
BufferedWriter bw;
Socket socket;
String firstLine;
String path;
int contentLength = 0;
byte [] content;
void startTransaction() throws IOException
{
InputStreamReader i = new InputStreamReader(socket.getInputStream());
br = new BufferedReader(i);
OutputStreamWriter o = new OutputStreamWriter(socket.getOutputStream());
bw = new BufferedWriter(o);
firstLine = null;
path = null;
contentLength = 0;
content = null;
doTransaction();
flush();
socket.close();
}
String readStr() throws IOException
{
String s = br.readLine();
return s;
}
char [] readBytes(int n) throws IOException
{
char [] buf = new char[n];
br.read(buf, 0, n);
return buf;
}
void writeStr(String s) throws IOException
{
bw.write(s, 0, s.length());
}
void flush() throws IOException
{
bw.flush();
}
void skipHeaders() throws IOException
{
String s;
while(true)
{
s = readStr();
if(s == null)
break;
s = s.trim();
if(s.equals(""))
break;
if(
s.startsWith("Content-Length: ") ||
s.startsWith("Content-length: ") ||
s.startsWith("content-length: ")
)
{
contentLength = (int)atol(s.substring(16));
}
}
}
void doTransaction() throws IOException
{
firstLine = readStr();
if(firstLine == null)
return;
path = firstLine;
int x = path.indexOf(' ');
if(x == -1)
{
defaultTransaction();
return;
}
path = path.substring(x + 1);
x = path.indexOf(' ');
if(x == -1)
{
defaultTransaction();
return;
}
path = path.substring(0, x);
int qu = path.indexOf('?');
if(qu != -1)
{
path = path.substring(0, qu);
}
skipHeaders();
// Is it a file?
String fpath = "./"+path;
File file = new File(fpath);
if(file.isFile())
{
fileTransaction(file);
return;
}
// No clue.
defaultTransaction();
}
// Return a file to the client.
void fileTransaction(File file) throws IOException
{
// write the http response headers
writeStr("HTTP/1.0 200 OK\n");
writeStr("Server: "+getClass().getName()+" 1.0\n");
// Make some half-hearted attempt to provide a content-type
String nl = file.getName().toLowerCase();
if(nl.endsWith(".html"))
writeStr("Content-Type: text/html\n");
else
if(nl.endsWith(".txt"))
writeStr("Content-Type: text/plain\n");
else
if(nl.endsWith(".java"))
writeStr("Content-Type: text/plain\n");
else
if(nl.endsWith(".jpg"))
writeStr("Content-Type: image/jpeg\n");
else
if(nl.endsWith(".bmp"))
writeStr("Content-Type: image/bmp\n");
else
if(nl.endsWith(".jpeg"))
writeStr("Content-Type: image/jpeg\n");
else
if(nl.endsWith(".gif"))
writeStr("Content-Type: image/gif\n");
else
if(nl.endsWith(".hdml"))
writeStr("Content-Type: text/x-hdml\n");
else
if(nl.endsWith(".wml"))
writeStr("Content-Type: text/vnd.wap.wml\n");
else
if(nl.endsWith(".wbmp"))
writeStr("Content-Type: image/vnd.wap.wbmp\n");
// write out length
long len = file.length();
writeStr("Content-Length: "+len+"\n");
// separated with a blank line
writeStr("\n");
flush();
// write out the file
FileInputStream fis = new FileInputStream(file);
OutputStream sos = socket.getOutputStream();
byte [] buf = new byte[BUF_SIZE];
long n = 0;
int r;
while(true)
{
r = fis.read(buf);
if(r == -1)
break;
sos.write(buf, 0, r);
n += r;
if(DELAY > 0)
{
try { Thread.sleep(DELAY); } catch(InterruptedException e) { }
}
}
sos.flush();
fis.close();
}
// Send back "I can't find what you requested" response
void defaultTransaction() throws IOException
{
String ip = socket.getInetAddress().getHostAddress();
htmlMsg("HTTPDaemon
Document not found.", 404);
flush(); // on your way, my lovelies!
}
// Write out a message as an html page.
void htmlMsg(String msg, int code) throws IOException
{
// write the http response headers
writeStr("HTTP/1.0 "+code+" OK\n");
writeStr("Server: "+getClass().getName()+" 1.0\n");
writeStr("Content-Type: text/html\n");
// separated with a blank line
writeStr("\n");
// write out the html
writeStr("\n");
writeStr("