home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2001 April
/
PCWorld_2001-04_cd.bin
/
Software
/
TemaCD
/
smartcache
/
src
/
httpreq.java
< prev
next >
Wrap
Text File
|
2001-01-26
|
10KB
|
342 lines
/*
* Smart Cache, http proxy cache server
* Copyright (C) 1998, 1999 Radim Kolar
*
* Smart Cache is Open Source Software; you may redistribute it
* and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2, or (at your option) any later version.
*
* This program distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* A copy of the GNU General Public License is available as
* /usr/doc/copyright/GPL in the Debian GNU/Linux distribution or on
* the World Wide Web at http://www.gnu.org/copyleft/gpl.html. You
* can also obtain it by writing to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
/* bugs */
/* nepodporuje multi-line hlavicky. Pouziva to vubec nekdo? */
/* turn off cache file je neefektivni (neodstranuje lf ze seznamu) */
public final class httpreq implements Runnable
{
public static InetAddress allowed[];
public static final int REQUEST_GET=1;
public static final int REQUEST_POST=2;
public static final int REQUEST_HEAD=3;
public static final int REQUEST_OPTIONS=4;
public static final int REQUEST_PUT=5;
public static final int REQUEST_DELETE=6;
public static final int REQUEST_TRACE=7;
public static final int REQUEST_CONNECT=8;
public static final int REQUEST_MIN=REQUEST_GET;
public static final int REQUEST_MAX=REQUEST_CONNECT;
public static mgr mgr;
public static String visible_hostname;
public static String visible_link;
public static int client_timeout;
public static DateFormat formatter= new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss", Locale.US);
public static String timezone;
/* access.log */
public static String logpatterns[];
public static DataOutputStream logfilez[];
public static String logfilenames[];
private Socket socket = null;
httpreq(Socket socket) {
this.socket=socket;
}
final public static String methodToString(int method)
{
switch(method)
{
case REQUEST_GET:
return "GET";
case REQUEST_POST:
return "POST";
case REQUEST_HEAD:
return "HEAD";
case REQUEST_PUT:
return "PUT";
case REQUEST_OPTIONS:
return "OPTIONS";
case REQUEST_DELETE:
return "DELETE";
case REQUEST_CONNECT:
return "CONNECT";
case REQUEST_TRACE:
return "TRACE";
default:
return "UNKNOWN";
}
}
final public void run() {
boolean http10=true;
try { DataInputStream in=new DataInputStream (new BufferedInputStream(socket.getInputStream()));
DataOutputStream ou=new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
/* precteme radku GET / */
socket.setSoTimeout(client_timeout);
String req=in.readLine();
if(req==null) { socket.close();ou.close();return;}
String req2=null;
if(allowed!=null) {
InetAddress adr;
adr=socket.getInetAddress();
int j=allowed.length;
boolean Block=true;
for(int i=0;i<j;i++) {
if (adr.equals(allowed[i])) Block=false;
}
if (Block)
server_error(http10,403,"Cache access denied.",ou);
}
int req_method=0;
Vector headers=new Vector();
if (req.indexOf(" HTTP/",0)==-1) http10=false;
StringTokenizer st=new StringTokenizer(req);
try{
req2=st.nextToken();
if(req2.equals("GET")) req_method=REQUEST_GET;
else
if(req2.equals("POST")) req_method=REQUEST_POST;
else
if(req2.equals("HEAD")) req_method=REQUEST_HEAD;
else
if(req2.equals("OPTIONS")) req_method=REQUEST_OPTIONS;
else
if(req2.equals("PUT")) req_method=REQUEST_PUT;
else
if(req2.equals("TRACE")) req_method=REQUEST_TRACE;
else
if(req2.equals("DELETE")) req_method=REQUEST_DELETE;
else
if(req2.equals("CONNECT")) req_method=REQUEST_CONNECT;
else
server_error(http10,501,"Method "+req2+" not implemented.",ou);
req2=st.nextToken();
}
catch (NoSuchElementException e) { server_error(http10,400,"Incomplete request",ou);}
/* HTTP 1.0+ - musime precist zbytek volovin az do prazdne radky */
if(http10) while(true)
{ req=in.readLine();
if(req==null) break;
if(req.length()==0) break;
headers.addElement(req);
}
/* zaciname zpracovavat requesty */
request rq;
try{
if (http10) rq=new request(req_method,req2,headers,in,ou);
else
rq=new request(req_method,req2,null,in,ou);
/* zalogovat do access.logu */
if(logpatterns!=null)
{
int j=logpatterns.length;
String urlcache=rq.getURL();
for(int i=0;i<j;i++)
{
String fragment;
fragment=mgr.simpleWildMatch(logpatterns[i], urlcache);
if(fragment==null) continue;
DataOutputStream outfile;
outfile=logfilez[i];
if(outfile==null && logfilenames[i]!=null)
/* OPEN LOGFILE */
if(!open_logfile(logfilenames,logfilez,i)) break;
else
outfile=logfilez[i];
/* ZAHAJUJEME LOGOVANI ! */
InetAddress adr;
adr=socket.getInetAddress();
// DataOutputStream log;
StringBuffer sb=new StringBuffer(90);
sb.append(adr.getHostAddress());
// log.writeBytes(adr.getHostAddress());
sb.append(" - - [");
sb.append(formatter.format(new Date()));
sb.append(timezone);
sb.append(methodToString(req_method));
sb.append(" ");
if(logpatterns[i]==null) sb.append(fragment+"\" 200 -\n");
else
sb.append("/"+fragment+"\" 200 -\n");
synchronized (outfile)
{
try
{
outfile.writeBytes(sb.toString());
}
catch (IOException errr) { logfilez[i]=null; }
}
// log.flush();
} /* log for */
}/* log enabled? */
try
{
mgr.process_request(rq);
}
catch (EOFException DONE) {}
catch (IOException transfer_error)
{
// System.out.println("[debug] I/O error when serving "+rq.getURL());
socket.setSoLinger(true,10*1000);
throw transfer_error;
}
} /* main loop try */
catch(MalformedURLException e2) { server_error(http10,400,"Invalid URL syntax",ou);}
}
catch (IOException main_transfer_error) {}
finally {
/* zkusime zavrit hlavni socket */
try {
/*
try
{
socket.setSoTimeout(0);
}catch (IOException ignoreit) {}
*/
socket.close();
}
catch (IOException jejda) {}
};
return;
}
final public static void server_error(boolean http10,int errorrc,String msg,
DataOutputStream ou) throws IOException
{
StringBuffer sb=new StringBuffer(1024);
if(http10) {
sb.append("HTTP/1.0 ");
sb.append(errorrc);
sb.append(" ERROR\r\nContent-type: text/html\r\nLast-Modified: ");
String ted=request.printDate(new Date());
sb.append(ted);
sb.append("\r\nDate: ");
sb.append(ted);
sb.append("\r\nExpires: ");
sb.append(request.printDate(new Date( new Date().getTime()+5*60*1000L )));
sb.append("\r\nServer: ");
sb.append(scache.VERSION);
sb.append("\r\nConnection: close\r\nProxy-Connection: close\r\n\r\n");
}
sb.append("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD><TITLE>Error</TITLE></HEAD>\n<BODY><h2>");
sb.append(errorrc);
sb.append(" ");
sb.append(msg);
sb.append("</h2>\r\n<hr noshade size=1>\r\nGenerated by ");
sb.append(visible_hostname);
sb.append(" (");
if(visible_link!=null)
{
sb.append("<a href=\"");
sb.append(visible_link);
sb.append("\">");
}
sb.append(scache.VERSION);
if(visible_link!=null)
{
sb.append("</a>");
}
sb.append(")\r\n</BODY></HTML>\r\n");
ou.writeBytes(sb.toString());
ou.close();
throw new EOFException("Request processing canceled");
}
/* pokusi se otevrit protokolacni soubor */
public final static boolean
open_logfile(String xlogfilenames[], DataOutputStream xlogfilez[], int i)
{
/* OPEN LOGFILE */
{
try{
DataOutputStream dos;
dos=new DataOutputStream(new BufferedOutputStream(
new FileOutputStream(xlogfilenames[i],true),4096));
xlogfilez[i]=dos;
}
catch (IOException e1)
{
System.err.println("Problem creating logfile "+xlogfilenames[i]+" - turning it off");
xlogfilenames[i]=null;
return false;
}
} /* logfile open */
return true;
}
public final static void flush(DataOutputStream xlogfilez[])
{
if(xlogfilez!=null)
for(int z=0;z<xlogfilez.length;z++)
{
if(xlogfilez[z]!=null)
try{
xlogfilez[z].flush();
}
catch(IOException e)
{}
}
}
public final static void close(DataOutputStream xlogfilez[])
{
if(xlogfilez!=null)
for(int z=0;z<xlogfilez.length;z++)
{
if(xlogfilez[z]!=null)
try{
xlogfilez[z].close();
}
catch(IOException e)
{}
finally
{
xlogfilez[z]=null;
}
}
}
} /* class */