📄 httprequest.java
字号:
/**
* Copyright (C) 2003 Manfred Andres
*
* This program is free software; you can 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
* of the License, or (at your option) any later version.
*
* This program is 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package freecs.content;
import freecs.*;
import freecs.core.*;
import freecs.util.EntityDecoder;
import freecs.interfaces.*;
import freecs.content.Connection;
import java.util.Properties;
import java.util.Enumeration;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.Charset;
import java.nio.charset.CharacterCodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* implementation of a HTTP-Request
* parses the http-header and stores the neccesary data
* as properties which may be accessed by the getProperty-Method
*/
public class HTTPRequest implements IRequest {
private SelectionKey key;
private CharBuffer buf;
private Properties props;
private String method, action, cookie, userAgent;
private boolean isHTTP11;
private ConnectionBuffer rb;
private boolean wrongAddress = false;
private Properties cookies = null;
private Connection conn;
public HTTPRequest (ByteBuffer buf, ConnectionBuffer rb) throws CharacterCodingException {
this.rb = rb;
this.key = rb.getKey ();
this.buf = Charset.forName (Server.srv.DEFAULT_CHARSET).newDecoder ().decode (buf);
}
public ConnectionBuffer getConnectionBuffer () {
return rb;
}
/**
* parses the HTTP request
*/
public void parse () throws Exception {
props = new Properties ();
String request = buf.toString ();
String parts[] = request.split ("\r\n\r\n");
String hf[] = parts[0].split ("\r\n");
String values[] = hf[0].split (" ");
method=values[0];
action=values[1];
isHTTP11 = values[2].equals ("HTTP/1.1") && Server.srv.USE_HTTP11;
if (!isHTTP11 && parts.length > 1 && parts[1].substring (parts[1].length () - 2).equals ("\r\n")) {
// it looks like http/1.0 has an extra \r\n after the values of a post-request (not included in content length)
parts[1] = parts[1].substring (0, parts[1].length () - 2);
}
int pos = action.indexOf ("?");
if (pos > -1) {
String rest = action.substring (pos + 1);
action = action.substring (0, pos);
String prt[] = rest.split("&");
for (int i = 0; i < prt.length; i++) {
String keyval[] = prt[i].split ("=");
if (keyval.length < 2) continue;
keyval[0] = EntityDecoder.entityToChar (keyval[0]);
if (keyval[0].equalsIgnoreCase ("message"))
keyval[1] = EntityDecoder.entityToHtml (keyval[1].trim ());
else
keyval[1] = EntityDecoder.entityToChar (keyval[1].trim ());
StringBuffer tsb = new StringBuffer ("value_").append (keyval[0].trim ());
props.setProperty (tsb.toString (), keyval[1]);
}
}
boolean refererFound = false, isProxyConnection = false;
String[] fwChain = null;
String realIp = null;
for (int i = 1; i < hf.length; i++) {
int dp = hf[i].indexOf (":");
if (dp == -1) continue;
String key = hf[i].substring (0, dp).trim ();
String value = hf[i].substring (dp +1).trim ();
if (key.equals ("Host")) {
String hst = value.split (":")[0];
InetAddress ia = InetAddress.getByName (hst);
if (!ia.equals (Server.srv.lh) && !hst.equalsIgnoreCase(Server.srv.SERVER_NAME)) {
StringBuffer tsb = new StringBuffer ("Illegal HTTP/1.1-request (Host-entity doesn't match localhost(").append (ia.toString ()).append (" != ").append (Server.srv.lh.toString ()).append ("))");
throw new Exception (tsb.toString ());
}
if (Server.srv.COOKIE_DOMAIN != null && !hst.endsWith (Server.srv.COOKIE_DOMAIN)) {
wrongAddress = true;
cookie = null;
Server.log ("Wrong adress used: " + hst + " instead of something ending with " + Server.srv.COOKIE_DOMAIN, Server.MSG_STATE, Server.LVL_MAJOR);
}
} else if (!Server.srv.ALLOW_EXTERNAL && key.equals ("Referer:")) {
if (value.indexOf ("/") > 0)
value = value.substring (0, value.indexOf ("/"));
for (Enumeration e = Server.srv.allowedLoginHosts.elements (); e.hasMoreElements (); ) {
InetAddress ia = InetAddress.getByName (value);
if (((InetAddress) e.nextElement ()).equals (ia)) {
refererFound = true;
break;
}
}
} else if (key.equals ("Cookie") && !wrongAddress) {
String cookiePair[] = value.split (";");
for (int j = 0; j < cookiePair.length; j++) {
String cp[] = cookiePair[j].split ("=");
if (cp.length < 2) continue;
if (!cookiePair[j].trim ().startsWith("FreeCSSession")) {
if (cookies==null) cookies = new Properties();
cookies.put(cp[0], cp[1]);
continue;
}
cookie = cp[1].trim ();
}
} else if (key.equalsIgnoreCase ("x-forwarded-for")) {
isProxyConnection = true;
fwChain = value.split(",");
} else if (key.equalsIgnoreCase ("via")) {
isProxyConnection = true;
} else if (key.equalsIgnoreCase ("client-ip")) {
isProxyConnection = true;
realIp = value;
} else if (key.equals("User-Agent")) {
userAgent = value;
} else {
props.setProperty (key, value);
}
}
conn = new Connection (this.key, fwChain, !isProxyConnection);
if (realIp != null) try {
InetAddress realAddress = InetAddress.getByName(realIp);
conn.realAddress = realAddress;
conn.realIp = realIp;
} catch (UnknownHostException uhe) {
Server.debug ("HTTPRequest.parse: Headerfield client-IP contains an UnknownHost", uhe, Server.MSG_STATE, Server.LVL_MINOR);
}
if (parts.length < 2 || (!Server.srv.ALLOW_EXTERNAL && !refererFound)) return;
hf = parts[1].split ("&");
for (int i = 0; i < hf.length; i++) {
String pair[] = hf[i].split ("=");
if (pair.length < 2) continue;
pair[0] = EntityDecoder.entityToChar (pair[0]);
if (pair[0].equalsIgnoreCase ("message"))
pair[1] = EntityDecoder.entityToHtml (pair[1].trim ());
else
pair[1] = EntityDecoder.entityToChar (pair[1].trim ());
StringBuffer tsb = new StringBuffer ("value_").append (pair[0]);
props.setProperty (tsb.toString (), pair[1]);
}
}
/**
* get properties of this request
* @param key the name of this property
* @return the value of the property identified by this key
*/
public String getProperty (String key) {
return props.getProperty (key);
}
public String getMethod () {
return method;
}
public String getAction () {
return action;
}
public boolean isHTTP11 () {
return isHTTP11;
}
public String getCookie () {
return cookie;
}
public String getUserAgent() {
return userAgent;
}
public String getProtokol () {
return isHTTP11 ? "HTTP/1.1" : "HTTP/1.0";
}
public Connection getConnectionObject() {
return conn;
}
/**
* gets the charsetDecoder for a given charset
* @param string the name of the charset
* @return a CharsetDecoder for this charset
*/
public CharsetDecoder getCharsetDecoder (String csName) {
return (Charset.forName (csName).newDecoder ());
}
public SelectionKey getKey () {
return key;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -