S O U R C E C O D E
/ 1999 / 08
/ java
/ 1.lst
// Small HTTP Server by Al Williams (Web Techniques, 8/99)
// This code is based on the Webster server at
// www.xs4all.nl/~somebody/java/webster.html
// which is covered by the GNU General Public License
// detailed at http://www.gnu.org/copyleft/gpl.html
import java.net.*;
import java.io.*;
import java.util.*;
public class HttpServer implements Runnable {
private ServerSocket ss;
private Thread runner=null;
// The server's configuration information is stored in these properties
protected static Properties props = new Properties();
// The mime types information is stored in this properties list
protected static Properties MimeTypes = new Properties();
HttpServer() { // main constructor
runner = new Thread(this);
runner.start();
}
public static void main(String[] args) {
new HttpServer();
}
// override this to provide an action
public String action(String filename, Hashtable vars) {
System.out.println("Serving: "+filename + " " + vars);
return filename;
}
public void run() {
try{
loadProps();
loadMimes();
System.out.println("HttpServer listening on port:" +
props.getProperty("portnumber"));
// setup serversocket
ss = new ServerSocket( (new Integer(props.getProperty
("portnumber"))).intValue() );
while(true) {
Socket s = ss.accept(); // accept incoming requests
new Thread(new SendFile(this,s)).start();
}
} catch(Exception e) {
System.out.println("Main Serve thread " + e );
}
}
// load the properties file
static void loadProps() throws IOException {
File f = new File("server.properties");
if (f.exists()) {
InputStream is =
new BufferedInputStream(new FileInputStream(f));
props.load(is);
is.close();
}
} // end of loadProps
// load the properties file
static void loadMimes() throws IOException {
File f = new File("mimetypes.properties");
if (f.exists()) {
InputStream is =
new BufferedInputStream(new FileInputStream(f));
MimeTypes.load(is);
is.close();
}
} // end of loadMimes
} // end of Serve class
class SendFile implements Runnable{
private Socket client;
private String fileName,header;
private String query;
private DataInputStream requestedFile;
private int fileLength;
private HttpServer svr;
SendFile(HttpServer svr,Socket s) { // constructor
client = s;
this.svr=svr;
}
public void run() {
String line;
try {
BufferedReader dis =
new BufferedReader(new InputStreamReader
(client.getInputStream()));
// read request from browser and parse
while((line=dis.readLine())!=null) {
StringTokenizer tokenizer = new StringTokenizer(line," ");
if (!tokenizer.hasMoreTokens()) break;
if (tokenizer.nextToken().equals("GET")) {
fileName = tokenizer.nextToken();
if (fileName.endsWith("/")) {
fileName = fileName +
HttpServer.props.getProperty("defaultfile");
} else {
fileName = fileName.substring(1);
}
}
}
if (fileName.charAt(0)!='/') fileName = "/" + fileName;
int n=fileName.indexOf('?');
if (n!=-1) {
query=fileName.substring(n+1);
fileName=fileName.substring(0,n);
}
else
query="";
fileName=URLDecode(fileName);
// decode query string
Hashtable qvars = new Hashtable(64);
int n0,n1;
do {
String val,key;
n0=query.indexOf('&');
if (n0==-1) n0=query.length();
if (n0<=0) break;
String vpart = query.substring(0,n0);
if (n0==query.length()) query="";
else query=query.substring(n0+1);
n1=vpart.indexOf('=');
if (n1==-1) {
val="";
key=vpart;
} else {
val = vpart.substring(n1+1);
key = vpart.substring(0,n1);
}
qvars.put(URLDecode(key),URLDecode(val));
} while (!query.equals(""));
fileName=svr.action(fileName,qvars);
try {
requestedFile = new DataInputStream(
new BufferedInputStream (new
FileInputStream(HttpServer.props.
getProperty("root") + fileName)));
fileLength = requestedFile.available();
constructHeader();
} catch(IOException e) { // file not found send 404.
header = "HTTP/1.0 404 File not found\n" +
"Allow: GET\n" +
"MIME-Version: 1.0\n"+
"Server : HttpServer: a Java Local HTTP Server\n"+
"\n\n <H1>404 File not Found</H1>\n";
fileName = null;
}
int i;
DataOutputStream clientStream =
new DataOutputStream(new BufferedOutputStream(client.
getOutputStream()));
clientStream.writeBytes(header);
if (fileName != null) {
while((i = requestedFile.read()) != -1) {
clientStream.writeByte(i);
}
}
clientStream.flush();
clientStream.close();
dis.close();
client.close();
if (requestedFile!=null) requestedFile.close();
} catch(Exception e) {
System.out.print("Error closing Socket\n"+e);
}
}
public String URLDecode(String in)
{
StringBuffer out = new StringBuffer(in.length());
int i = 0;
int j = 0;
while (i < in.length())
{
char ch = in.charAt(i); i++;
if (ch == '+') ch = ' ';
else if (ch == '%')
{
ch = (char) Integer.parseInt(
in.substring(i,i+2), 16);
i+=2;
}
out.append(ch);
j++;
}
return new String(out);
}
private void constructHeader() {
String fileType;
fileType = fileName.substring(fileName.
lastIndexOf(".")+1,fileName.length());
fileType = HttpServer.MimeTypes.getProperty(fileType);
header = "HTTP/1.0 200 OK\n" +
"Allow: GET\nMIME-Version: 1.0\n"+
"Server : HttpServer : a Java Local HTTP Server\n"+
"Content-Type: " + fileType + "\n"+
"Content-Length: " + fileLength +
"\n\n";
}
}
|
HOME
|
CURRENT ISSUE
|
ARCHIVES
|
SOURCE CODE
|
EVENTS
|
BUYER'S GUIDE
|
CUSTOMER SERVICE
|
ADVERTISING
|
AUTHOR GUIDELINES
|
EDITORIAL CALENDAR
|
SEARCH
|
ABOUT
Entire contents copyright 1996-2000 Miller Freeman, Inc.
Read our privacy policy.