很棒的web服务器源代码

源代码在线查看: request.java

软件大小: 8570 K
上传用户: ivanyeh
关键词: web 服务器 源代码
下载地址: 免注册下载 普通下载 VIP

相关代码

				// Request.java				// $Id: Request.java,v 1.37 2003/01/08 12:40:36 ylafon Exp $				// (c) COPYRIGHT MIT and INRIA, 1996.				// Please first read the full copyright statement in file COPYRIGHT.html								package org.w3c.jigsaw.http ;								import java.io.IOException;				import java.io.InputStream;								import java.net.URL;								import org.w3c.www.mime.MimeParser;								import org.w3c.www.http.ChunkedInputStream;				import org.w3c.www.http.ContentLengthInputStream;				import org.w3c.www.http.HTTP;				import org.w3c.www.http.HttpCredential;				import org.w3c.www.http.HttpEntityMessage;				import org.w3c.www.http.HttpFactory;				import org.w3c.www.http.HttpMessage;				import org.w3c.www.http.HttpParserException;				import org.w3c.www.http.HttpRequestMessage;								import org.w3c.tools.resources.ReplyInterface;				import org.w3c.tools.resources.RequestInterface;				import org.w3c.tools.resources.ResourceFilter;				import org.w3c.tools.resources.ResourceReference;								import org.w3c.tools.codec.Base64Encoder;								/**				 * this class extends HttpRequestMessage to cope with HTTP request.				 * One subtely here: note how each field acessor never throws an				 * exception, but rather is provided with a default value: this is in the hope				 * that sometime, HTTP will not require all the parsing it requires right now.				 */								public class Request extends HttpRequestMessage 				    implements RequestInterface				{				    /**				     * The URL that means * for an OPTIONS				     * method.				     */				    public static URL THE_SERVER = null;								    /**				     * the state of original URL				     */				    public static final String ORIG_URL_STATE = 				                                         "org.w3c.jigsaw.http.Request.origurl";								    static {					try {					    THE_SERVER = new URL("http://your.url.unknown");					} catch (Exception ex) {					    ex.printStackTrace();					}				    }								    protected Client      client  = null;				    protected MimeParser  parser  = null;				    protected InputStream in      = null;				    protected boolean     keepcon = true;				    boolean is_proxy = false;								    public void setState(String name, String state) {					super.setState(name, state);				    }								    /**				     * Fix the target URL of the request, this is the only good time to do so.				     * @param parser The MimeParser				     * @exception HttpParserException if parsing failed.				     * @exception IOException if an IO error occurs.				     */								    public void notifyEndParsing(MimeParser parser)					throws HttpParserException, IOException					{					    super.notifyEndParsing(parser);					    String target = getTarget();					    String url    = null;					    // Get rid of the nasty cases(there is a place in hell for someone)					    if ( target.equals("*") ) {						setURL(THE_SERVER);						return;					    }					    // Is this a full http URL:					    int    at    = -1;					    int    colon = target.indexOf(':');					    String proto = (colon != -1) ? target.substring(0, colon) : null;					    if ((proto != null) &&						(proto.equals("http") || proto.equals("ftp"))) {						// Good we have a full URL:						try {						    // hugly hack, bug in URL for urls like:						    // http://user:passwd@host:port/file						    if ((at = target.indexOf('@',6)) != -1) {							String auth = target.substring(colon+3,at);							int    sep  = -1;							if ((auth.indexOf('/') == -1) &&				 			    ((sep = auth.indexOf(':')) != -1)) {							    if (! hasAuthorization()) {								String username = auth.substring(0,sep);								String password = auth.substring(sep+1);								HttpCredential credential =								    HttpFactory.makeCredential("Basic");								Base64Encoder encoder = 								    new Base64Encoder(username+":"+password);								credential.setAuthParameter("cookie", 				 						     encoder.processString());								setAuthorization(credential);							    }							    setURL(new URL(proto+									   "://"+target.substring(at+1)));							} else {							    setURL(new URL(target));							}						    } else {							setURL(new URL(target));						    }						} catch (Exception ex) {						    throw new HttpParserException("Bogus URL ["+url+"]", this);						}					    } else {						try {						    // Do we have a valid host header ?						    String host = getHost();						    if ( host == null ) {							// If this claims to be 1.1, tell him he's wrong:							if ((major == 1) && (minor >= 1))							    throw new HttpParserException("No Host Header");							httpd server = getClient().getServer();							setURL(new URL("http"								       , server.getHost(), server.getPort()								       , target));						    } else {							int ic = host.indexOf(':');							if ( ic < 0 ) {							    setURL(new URL("http", host, target));							} else {							    setURL(new URL("http"									   , host.substring(0, ic)									   , Integer.parseInt(									       host.substring(ic+1))									   , target));							}						    }						} catch (Exception ex) {						    throw new HttpParserException("Bogus URL ["+url+"]", this);						}					    }					}								    // FIXME				    // This guy should also check that the (optional) request stream has been				    // exhausted.								    public boolean canKeepConnection() {					// HTTP/0.9 doesn't know about keeping connections alive:					if (( ! keepcon) || (major < 1))					    return false;					if ( minor >= 1 ) 					    // HTTP/1.1 keeps connections alive by default					    return hasConnection("close") ? false : true;					// For HTTP/1.0 check the [proxy] connection header:					if ( is_proxy )					    return hasProxyConnection("keep-alive");					else					    return hasConnection("keep-alive");				    }								    private ResourceReference target_resource = null;				    protected void setTargetResource(ResourceReference resource) {					target_resource = resource;				    }								    /**				     * Get this request target resource.				     * @return An instance of HTTPResource, or null if				     * not found.				     */								    public ResourceReference getTargetResource() {					return target_resource;				    }								    public void setProxy(boolean onoff) {					is_proxy = onoff;				    }								    public boolean isProxy() {					return is_proxy;				    }								    public String getURLPath() {					return url.getFile();				    }								    public void setURLPath(String path) {					try {					    url = new URL(url, path);					} catch (Exception ex) {					    ex.printStackTrace();					}				    }								    public boolean hasContentLength() {					return hasHeader(H_CONTENT_LENGTH);				    }								    public boolean hasContentType() {					return hasHeader(H_CONTENT_TYPE);				    }								    public boolean hasAccept() {					return hasHeader(H_ACCEPT);				    }								    public boolean hasAcceptCharset() {					return hasHeader(H_ACCEPT_CHARSET);				    }								    public boolean hasAcceptEncoding() {					return hasHeader(H_ACCEPT_ENCODING);				    }								    public boolean hasAcceptLanguage() {					return hasHeader(H_ACCEPT_LANGUAGE);				    }								    public boolean hasAuthorization() {					return hasHeader(H_AUTHORIZATION);				    }								    public boolean hasProxyAuthorization() {					return hasHeader(H_PROXY_AUTHORIZATION);				    }								    public String getQueryString() {					return (String) getState("query");				    }								    public boolean hasQueryString() {					return hasState("query");				    }								    protected boolean internal = false;				    public boolean isInternal() {					return internal;				    }								    public void setInternal(boolean onoff) {					this.internal = onoff;				    }								    protected Request original = null;				    public Request getOriginal() {					return original == null ? this : original ;				    }								    protected ResourceFilter filters[] = null;				    protected int        infilters = -1;				    protected void setFilters(ResourceFilter filters[], int infilters) {					this.filters   = filters;					this.infilters = infilters;				    }								    /**				     * Clone this request, in order to launch an internal request.				     * This method can be used to run a request in some given context, defined				     * by an original request. It will preserve all the original information				     * (such as authentication, etc), and will provide a clone of				     * the original request.				     * The original request and its clone differ in the following way:				     * 				     * The clone is marked as internal, which can be tested				     * by the isInternal method.				     * The clone will keep a pointer to the first request that was 				     * cloned. This original request can be accessed by the getOriginal				     *  method.				     * 				     * To run an internal request, the caller can then use the 				     * org.w3c.jigsaw.http.httpd perform method.				     * @return A fresh Request instance, marked as internal.				     */								    public HttpMessage getClone() {					Request cl = (Request) super.getClone();					cl.internal = true;					if ( cl.original == null )					    cl.original = this;					return cl;				    }								    /**				     * Get this reply entity body.				     * The reply entity body is returned as an InputStream, that the caller				     * has to read to actually get the bytes of the content.				     * @return An InputStream instance. If the reply has no body, the returned				     * input stream will just return -1 on first read.				     */								    public InputStream getInputStream()					throws IOException					{					    if ( in != null )						return in;					    // Find out which method is used to the length:					    // first, chunked					    String te[] = getTransferEncoding() ;					    if ( te != null ) {						for (int i = 0 ; i < te.length ; i++) {						    if (te[i].equals("chunked")) 							in = new ChunkedInputStream(							    parser.getInputStream());						}					    }					    // if not, content-length					    int len = getContentLength();					    if ( (in == null) && (len >= 0) ) {						in = new ContentLengthInputStream(parser.getInputStream(),len);					    }					    // Handle broken HTTP/1.0 request					    // It is mandatory for 1.1 requests to have been handled above.					    if ((major == 1) && (minor == 0) && (in == null)) {						String m = getMethod();						if (m.equals("POST") || m.equals("PUT")) {						    keepcon = false;						    in      = parser.getInputStream();						}					    }					    return in;					}								    /**				     * Unescape a HTTP escaped string				     * @param s The string to be unescaped				     * @return the unescaped string.				     */								    public static String unescape (String s) {					StringBuffer sbuf = new StringBuffer () ;					int l  = s.length() ;					int ch = -1 ;					for (int i = 0 ; i < l ; i++) {					    switch (ch = s.charAt(i)) {					    case '%':						ch = s.charAt (++i) ;						int hb = (Character.isDigit ((char) ch) 							  ? ch - '0'							  : 10+Character.toLowerCase ((char) ch)-'a') & 0xF ;						ch = s.charAt (++i) ;						int lb = (Character.isDigit ((char) ch)							  ? ch - '0'							  : 10+Character.toLowerCase ((char) ch)-'a') & 0xF ;						sbuf.append ((char) ((hb 						break ;					    case '+':						sbuf.append (' ') ;						break ;					    default:						sbuf.append ((char) ch) ;					    }					}					return sbuf.toString() ;				    }								    public ReplyInterface makeBadRequestReply() {					return makeReply(HTTP.BAD_REQUEST);				    }								    /**				     * Make an empty Reply object matching this request version.				     * @param status The status of the reply.				     */								    public Reply makeReply(int status) {					Reply reply = new Reply(client								, this								, getMajorVersion()								, getMinorVersion()								, status);					if ((filters != null) && (infilters > 0))					    reply.setFilters(filters, infilters);					return reply;				    }								    /**				     * skip the body				     */				    public void skipBody() {					// don't skip when there is a 100-Continue					if (getExpect() != null)					    return;					try {					    InputStream is = getInputStream();					    int avail = is.available();					    					    while (avail > 0) {						is.skip(avail);						avail = is.available();					    }					} catch (Exception ex) {// nothing to skip 					}				    }								    /**				     * Get the client of this request.				     */								    public Client getClient() {					return client ;				    }								    public Request (Client client, MimeParser parser) {					super (parser);					this.parser = parser;					this.client = client ;				    }												    /**				     * Set this reply entity body.					 * @param is the InputStream instance. 					 * USE CAREFULLY : need to be thread-safe				     */				    public void setStream(InputStream is){					if (is != null)					    this.in = is ;				    }				}							

相关资源