📄 httpbasefilter.java
字号:
package rabbit.filter;import java.math.BigInteger;import java.net.MalformedURLException;import java.net.URL;import java.nio.channels.SocketChannel;import java.util.ArrayList;import java.util.Date;import java.util.List;import rabbit.http.HttpDateParser;import rabbit.http.HttpHeader;import rabbit.proxy.Connection;import rabbit.proxy.HttpGenerator;import rabbit.proxy.HttpProxy;import rabbit.util.Coder;import rabbit.util.Logger;import rabbit.util.SProperties;import rabbit.util.SimpleUserHandler;/** This is a class that filter http headers to make them nice. * This filter sets up username and password if supplied and * also sets up keepalive. * * @author <a href="mailto:robo@khelekore.org">Robert Olofsson</a> */public class HttpBaseFilter implements HttpFilter { public static final String NOPROXY = "http://noproxy."; private static final BigInteger ZERO = new BigInteger ("0"); private static final BigInteger ONE = new BigInteger ("1"); private List<String> removes = new ArrayList<String> (); private boolean cookieId = false; private SimpleUserHandler userHandler = new SimpleUserHandler (); /** */ public HttpBaseFilter () { } /** We got a proxy authentication, handle it... * @param uap the authentication string. * @param con the Connection. */ private void handleProxyAuthentication (String uap, Connection con) { // guess we should handle digest here also.. :-/ if (uap.startsWith ("Basic ")) { uap = uap.substring ("Basic ".length ()); String userapass = Coder.uudecode (uap); int i = -1; if ((i = userapass.indexOf (":")) > -1) { String userid = userapass.substring (0, i); String pass = userapass.substring (i + 1); con.setUserName (userid); con.setPassword (pass); } } } /** Handle the authentications. * If we have a proxy-authentication we set the * connections username and password. * We also rewrite authentications in the URL to a standard header, * since java does not handle them. * @param header the Request. * @param con the Connection. */ private void handleAuthentications (HttpHeader header, Connection con) { String uap = header.getHeader ("Proxy-Authorization"); if (uap != null) handleProxyAuthentication (uap, con); /* * Java URL:s doesn't handle user/pass in the URL as in rfc1738: * //<user>:<password>@<host>:<port>/<url-path> * * Convert these to an Authorization header and remove from URI. */ String requestURI = header.getRequestURI(); int s3, s4, s5; if ((s3 = requestURI.indexOf("//")) >= 0 && (s4 = requestURI.indexOf('/', s3 + 2)) >= 0 && (s5 = requestURI.indexOf('@', s3 + 2)) >= 0 && s5 < s4) { String userPass = requestURI.substring(s3 + 2, s5); header.setHeader("Authorization", "Basic " + Coder.uuencode(userPass)); header.setRequestURI(requestURI.substring(0, s3 + 2) + requestURI.substring(s5 + 1)); } } /** Check if this is a noproxy request, and if so handle it. * @param requri the requested resource. * @param header the actual request. * @param con the Connection. * @return the new request URI */ private String handleNoProxyRequest (String requri, HttpHeader header, Connection con) { requri = "http://" + requri.substring (NOPROXY.length ()); header.setRequestURI (requri); con.setMayUseCache (false); con.setMayCache (false); con.setMayFilter (false); return requri; } /** Check that the requested URL is valid and if it is a meta request. * @param requri the requested resource. * @param header the actual request. * @param con the Connection. */ private HttpHeader handleURLSetup (String requri, HttpHeader header, Connection con) { try { // is this request to our self? HttpProxy proxy = con.getProxy (); if (requri != null && requri.charAt (0) == '/') { requri = "http://" + proxy.getHost ().getHostName () + ":" + proxy.getPort () + requri; header.setRequestURI (requri); } URL url = new URL (requri); header.setHeader ("Host", url.getPort () > -1 ? url.getHost () + ":" + url.getPort () : url.getHost ()); int urlport = url.getPort (); // This could give a DNS-error if no DNS is available. // And since we have not decided if we should proxy it // up the chain yet, do string comparison.. // InetAddress urlhost = InetAddress.getByName (url.getHost ()); String uhost = url.getHost (); if (proxy.isSelf (uhost, urlport)) { con.setMayUseCache (false); con.setMayCache (false); con.setMayFilter (false); if (!userHandler.isValidUser (con.getUserName (), con.getPassword ()) && !isPublic (url)) { HttpHeader ret = con.getHttpGenerator ().get407 (uhost + ":" + urlport, url); return ret; } con.setMeta (true); } } catch (MalformedURLException e) { return con.getHttpGenerator ().get400 (e); } return null; } /** Remove all "Connection" tokens from the header. * @param header the HttpHeader that needs to be cleaned. */ private void removeConnectionTokens (HttpHeader header) { List<String> cons = header.getHeaders ("Connection"); for (String val : cons) { /* ok, split it... */ int s = -1; int start = 0; while (start < val.length ()) { while (val.length () > start + 1 && (val.charAt (start) == ' ' || val.charAt (start) == ',')) start++; if (val.length () > start + 1 && val.charAt (start) == '"') { start++; s = val.indexOf ('"', start); while (s >= -1 && val.charAt (s - 1) == '\\' && val.length () > s + 1) s = val.indexOf ('"', s + 1); if (s == -1) s = val.length (); String t = val.substring (start, s).trim (); /* ok, unquote the value... */ StringBuilder sb = new StringBuilder (t.length ()); for (int c = 0; c < t.length (); c++) { char z = t.charAt (c); if (z != '\\') sb.append (z); } t = sb.toString (); header.removeHeader (t); s = val.indexOf (',', s + 1); if (s == -1) start = val.length (); else start = s + 1; } else { s = val.indexOf (',', start + 1); if (s == -1) s = val.length (); String t = val.substring (start, s).trim (); header.removeHeader (t); start = s + 1; } } } } private HttpHeader checkMaxForwards (Connection con, HttpHeader header, String val) { try { BigInteger bi = new BigInteger (val); if (bi.equals (ZERO)) { if (header.getMethod ().equals ("TRACE")) { HttpHeader ret = con.getHttpGenerator ().get200 (); ret.setContent (header.toString ()); return ret; } else { HttpHeader ret = con.getHttpGenerator ().get200 (); ret.setHeader ("Allow", "GET,HEAD,POST,OPTIONS,TRACE"); ret.setHeader ("Content-Length", "0"); return ret; } } else { BigInteger b3 = bi.subtract (ONE); header.setHeader ("Max-Forwards", b3.toString ()); } } catch (NumberFormatException e) { HttpProxy proxy = con.getProxy (); proxy.getLogger ().logWarn ("Bad number for Max-Forwards: '" + val + "'"); } return null; } /** test if a socket/header combination is valid or return a new HttpHeader. * @param socket the SocketChannel that made the request. * @param header the actual request made. * @param con the Connection handling the request. * @return null if everything is fine or a HttpHeader describing * the error (like a 403). */ public HttpHeader doHttpInFiltering (SocketChannel socket, HttpHeader header, Connection con) { // ok, no real header then dont do a thing. if (header.isDot9Request ()) { con.setMayCache (false); con.setMayUseCache (false); con.setKeepalive (false); return null; } handleAuthentications (header, con); boolean maychunk = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -