⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 request.java

📁 很棒的web服务器源代码
💻 JAVA
字号:
// 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.htmlpackage 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 <em>never</em> 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 <strong>*</strong> for an <code>OPTIONS</code>     * 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 <strong>null</strong> 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 <em>clone</em> of     * the original request.     * <p>The original request and its clone differ in the following way:     * <ul>     * <li>The clone is marked as <em>internal</em>, which can be tested     * by the <code>isInternal</code> method.     * <li>The clone will keep a pointer to the first request that was      * cloned. This original request can be accessed by the <code>getOriginal     * </code> method.     * </ul>     * <p>To run an internal request, the caller can then use the <code>     * org.w3c.jigsaw.http.httpd</code> <code>perform</code> 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 <strong>-1</strong> 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 << 4) | lb)) ;		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 ;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -