diff --git a/htroot/SettingsAck_p.html b/htroot/SettingsAck_p.html index 43e5f7a8d..da82012ec 100644 --- a/htroot/SettingsAck_p.html +++ b/htroot/SettingsAck_p.html @@ -30,8 +30,8 @@ Your new administration account name is #[user]#. The password has been accepted :: Your proxy access setting has been changed.
Your proxy account check has been disabled, since you did not supply a password.

- The new proxy IP filter is set to #[filter]#
- The proxy port is: #[port]#

+ The new proxy IP filter is set to

#[filter]#

+ The proxy port is:
#[port]#

#(restart)# :: Port rebinding will be done in a view seconds.
@@ -39,10 +39,10 @@ Your new administration account name is #[user]#. The password has been accepted #(/restart)# :: Your proxy access setting has been changed.
- Your new proxy account name is #[user]#. The password has been accepted.
+ Your new proxy account name is

#[user]#
. The password has been accepted.
If you open any public web page through the proxy, you must log-in then.

- The new proxy IP filter is set to #[filter]#.
- The proxy port is: #[port]#

+ The new proxy IP filter is set to #[filter]#.
+ The proxy port is:

#[port]#

#(restart)# :: Port rebinding will be done in a view seconds.
@@ -59,8 +59,8 @@ Auto pop-up of the Status page is now enabled
:: You are now permanently online. After a short while you should see the effect on the status page.
:: -The Peer Name is: #[peerName]#
-Your static Ip(or DynDns) is: #[staticIP]#
+The Peer Name is:

#[peerName]#

+Your static Ip(or DynDns) is:
#[staticIP]#

:: Seed Settings changed.#(success)#::You are now a principal peer.#(/success)#
:: @@ -73,11 +73,11 @@ Please return to the settings page and modify the data.
The new setting is effective immediately, you don't need to re-start. :: The submitted peer name is already used by another peer. Please choose a different name. The Peer name has not been changed.
-Your Peer Language is: #[peerLang]#
+Your Peer Language is:
#[peerLang]#

:: The submitted peer name is not well-formed. Please choose a different name. The Peer name has not been changed.
Peer names must not contain characters other than (a-z, A-Z, 0-9, '-', '_') and must not be longer than 80 characters. -Your Peer Language is: #[peerLang]#
+Your Peer Language is:
#[peerLang]#

::

The new parser settings where changed successfully.
@@ -85,7 +85,10 @@ Parsing of the following mime-types was enabled:

#{parser}# - + + + + #{/parser}#
#[parserMode]##[enabledMime]#
#[parserMode]##[enabledMime]#
:: @@ -93,19 +96,28 @@ Seed Upload method was changed successfully. #(success)#::
You are now a principal peer.#(/success)#

- - + + + + + + +
Seed Upload Method:#[seedUploadMethod]#
Seed File URL:#[seedURL]#
Seed Upload Method:#[seedUploadMethod]#
Seed File URL:#[seedURL]#
-:: +::

Your proxy networking settings have been changed.

- + - + + + + +
Transparent Proxy Support is:#[isTransparentProxy]##[isTransparentProxy]#
Connection Keep-Alive Support is:#[connectionKeepAliveSupport]##[connectionKeepAliveSupport]#
Send via header is:#[proxy.sendViaHeader]#
:: @@ -113,15 +125,15 @@ Seed Upload method was changed successfully. - + - + - +
Message Forwarding Support is:#[msgForwardingEnabled]##[msgForwardingEnabled]#
Message Forwarding Command:#[msgForwardingCmd]##[msgForwardingCmd]#
Recipient Address:#[msgForwardingTo]##[msgForwardingTo]#
:: @@ -129,19 +141,19 @@ Seed Upload method was changed successfully. - + - + - + - +
Port Forwarding Support is:#[portForwardingEnabled]##[portForwardingEnabled]#
Port Forwarding Port:#[portForwardingPort]##[portForwardingPort]#
Port Forwarding Host:#[portForwardingHostUser]#@#[portForwardingHost]#:#[portForwardingHostPort]##[portForwardingHostUser]#@#[portForwardingHost]#:#[portForwardingHostPort]#
Port Forwarding uses proxy:#[portForwardingUseProxy]##[portForwardingUseProxy]#
:: @@ -154,7 +166,7 @@ You are now event-based online. After a short while you should see the ef :: You are now in Cache Mode. Only Proxy-cache ist available in this mode. After a short while you should see the effect on the status page.
:: -

Unable to bild the server to the new Port: #[port]#
+

Unable to bild the server to the new Port:

#[port]#

This values seems not to be a valid port configuration. #(/info)#

diff --git a/htroot/SettingsAck_p.java b/htroot/SettingsAck_p.java index d4874c2e2..894eae19a 100644 --- a/htroot/SettingsAck_p.java +++ b/htroot/SettingsAck_p.java @@ -205,6 +205,10 @@ public class SettingsAck_p { env.setConfig("connectionKeepAliveSupport", httpd.keepAliveSupport ? "true" : "false"); prop.put("info_connectionKeepAliveSupport", httpd.keepAliveSupport ? "on" : "off"); + // setting via header property + env.setConfig("proxy.sendViaHeader", post.containsKey("proxy.sendViaHeader")?"true":"false"); + prop.put("info_proxy.sendViaHeader", post.containsKey("proxy.sendViaHeader")? "on" : "off"); + prop.put("info", 20); return prop; } diff --git a/htroot/Settings_Http.inc b/htroot/Settings_Http.inc index a7579f8c3..c6b3144cc 100644 --- a/htroot/Settings_Http.inc +++ b/htroot/Settings_Http.inc @@ -14,6 +14,11 @@ With this you can specify if YaCy should support the HTTP connection keep-alive feature. + + Send Via Header: + + Specifies if the proxy should send the Via http header according to RFC 2616 Sect 14.45. +  Changes will take effect immediately. diff --git a/htroot/Settings_p.java b/htroot/Settings_p.java index 52121b83f..24f10ccca 100644 --- a/htroot/Settings_p.java +++ b/htroot/Settings_p.java @@ -116,6 +116,7 @@ public final class Settings_p { // http networking settings prop.put("isTransparentProxy", env.getConfig("isTransparentProxy", "false").equals("true") ? 1 : 0); prop.put("connectionKeepAliveSupport", env.getConfig("connectionKeepAliveSupport", "false").equals("true") ? 1 : 0); + prop.put("proxy.sendViaHeader", env.getConfig("proxy.sendViaHeader", "false").equals("true") ? 1 : 0); // remote port forwarding settings prop.put("portForwardingEnabled",env.getConfig("portForwardingEnabled","false").equals("true")? 1 : 0); diff --git a/htroot/env/style.css b/htroot/env/style.css index 1cb557335..de67cef5a 100644 --- a/htroot/env/style.css +++ b/htroot/env/style.css @@ -198,8 +198,15 @@ width: 16px; } .ResultDescription { -color:#4070a0; -font-style:bold;} + color:#4070a0; + font-weight:bold; +} .ResultDateYBR { -color:#007050} + color:#007050 +} + +.settingsValue { + color:#556699; + font-weight:bold; +} diff --git a/source/de/anomic/http/httpHeader.java b/source/de/anomic/http/httpHeader.java index 1e92a09fb..eb232cc27 100644 --- a/source/de/anomic/http/httpHeader.java +++ b/source/de/anomic/http/httpHeader.java @@ -62,6 +62,7 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.text.Collator; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; @@ -69,6 +70,7 @@ import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Properties; +import java.util.TimeZone; import java.util.TreeMap; import java.util.Vector; @@ -94,35 +96,52 @@ public final class httpHeader extends TreeMap implements Map { public static final String ACCEPT = "Accept"; public static final String ACCEPT_CHARSET = "Accept-Charset"; public static final String ACCEPT_LANGUAGE = "Accept-Language"; - public static final String KEEP_ALIVE = "Keep-Alive"; - public static final String USER_AGENT = "User-Agent"; + + public static final String HOST = "Host"; + public static final String CONNECTION = "Connection"; + public static final String PROXY_CONNECTION = "Proxy-Connection"; + public static final String KEEP_ALIVE = "Keep-Alive"; + public static final String REFERER = "Referer"; - public static final String ACCEPT_ENCODING = "Accept-Encoding"; - public static final String CONTENT_LENGTH = "Content-Length"; - public static final String CONTENT_TYPE = "Content-Type"; + public static final String USER_AGENT = "User-Agent"; + public static final String AUTHORIZATION = "Authorization"; public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; public static final String PROXY_AUTHORIZATION = "Proxy-Authorization"; public static final String PROXY_AUTHENTICATE = "Proxy-Authenticate"; - public static final String PROXY_CONNECTION = "Proxy-Connection"; + public static final String DATE = "Date"; public static final String SERVER = "Server"; - public static final String LAST_MODIFIED = "Last-modified"; - public static final String PRAGMA = "Pragma"; + + public static final String CONTENT_LENGTH = "Content-Length"; + public static final String CONTENT_TYPE = "Content-Type"; + public static final String CONTENT_MD5 = "Content-MD5"; + public static final String SET_COOKIE = "Set-Cookie"; public static final String SET_COOKIE2 = "Set-Cookie2"; - public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; public static final String COOKIE = "Cookie"; public static final String EXPIRES = "Expires"; + + + public static final String ACCEPT_ENCODING = "Accept-Encoding"; public static final String CONTENT_ENCODING = "Content-Encoding"; + public static final String TRANSFER_ENCODING = "Transfer-Encoding"; + + public static final String ACCEPT_RANGES = "Accept-Ranges"; public static final String CONTENT_RANGE = "Content-Range"; public static final String RANGE = "Range"; + public static final String IF_RANGE = "If-Range"; + + public static final String PRAGMA = "Pragma"; public static final String CACHE_CONTROL = "Cache-Control"; - public static final String TRANSFER_ENCODING = "Transfer-Encoding"; + public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; + public static final String LAST_MODIFIED = "Last-modified"; + public static final String LOCATION = "Location"; public static final String ETAG = "ETag"; + public static final String VIA = "Via"; public static final String X_CACHE = "X-Cache"; public static final String X_CACHE_LOOKUP = "X-Cache-Lookup"; @@ -360,29 +379,47 @@ public final class httpHeader extends TreeMap implements Map { private static SimpleDateFormat EMLFormatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.US); public static Date parseHTTPDate(String s) { - if ((s == null) || (s.length() < 9)) return new Date(); - s = s.trim(); - if (s.charAt(3) == ',') s = s.substring(5).trim(); // we skip the name of the day - if (s.charAt(9) == ' ') s = s.substring(0, 7) + "20" + s.substring(7); // short year version - if (s.charAt(2) == ',') s = s.substring(0, 2) + s.substring(3); // ommit comma after day of week - if ((s.charAt(0) > '9') && (s.length() > 20) && (s.charAt(2) == ' ')) s = s.substring(3); - if (s.length() > 20) s = s.substring(0, 20).trim(); // truncate remaining, since that must be wrong + try { + return parseHTTPDate(s,true); + } catch (ParseException e) { + //System.out.println("ERROR long version parse: " + e.getMessage() + " at position " + e.getErrorOffset()); + serverLog.logSevere("HTTPC-header", "DATE ERROR (Parse): " + s); + return null; + } catch (java.lang.NumberFormatException e) { + //System.out.println("ERROR long version parse: " + e.getMessage() + " at position " + e.getErrorOffset()); + serverLog.logSevere("HTTPC-header", "DATE ERROR (NumberFormat): " + s); + return null; + } + } + + public static Date parseHTTPDate(String s,boolean ignoreTimezone) throws ParseException, NumberFormatException { + + SimpleDateFormat formatter = EMLFormatter; + if ((s == null) || (s.length() < 9)) return null; + s = s.trim(); + if (s.charAt(3) == ',') s = s.substring(5).trim(); // we skip the name of the day + if (s.charAt(9) == ' ') s = s.substring(0, 7) + "20" + s.substring(7); // short year version + if (s.charAt(2) == ',') s = s.substring(0, 2) + s.substring(3); // ommit comma after day of week + if ((s.charAt(0) > '9') && (s.length() > 20) && (s.charAt(2) == ' ')) s = s.substring(3); + if (s.length() > 20) { + if (!ignoreTimezone) { + formatter = (SimpleDateFormat) formatter.clone(); + formatter.setTimeZone(TimeZone.getTimeZone(s.substring(20))); + } + s = s.substring(0, 20).trim(); // truncate remaining, since that must be wrong + } if (s.indexOf("Mrz") > 0) s = s.replaceAll("Mrz", "March"); - try { - return EMLFormatter.parse(s); - } catch (java.text.ParseException e) { - //System.out.println("ERROR long version parse: " + e.getMessage() + " at position " + e.getErrorOffset()); - serverLog.logSevere("HTTPC-header", "DATE ERROR (Parse): " + s); - return new Date(); - } catch (java.lang.NumberFormatException e) { - //System.out.println("ERROR long version parse: " + e.getMessage() + " at position " + e.getErrorOffset()); - serverLog.logSevere("HTTPC-header", "DATE ERROR (NumberFormat): " + s); - return new Date(); - } + + // parsing the date string + return formatter.parse(s); } private Date headerDate(String kind) { - if (containsKey(kind)) return new Date(parseHTTPDate((String) get(kind)).getTime()); + if (containsKey(kind)) { + Date parsedDate = parseHTTPDate((String) get(kind)); + if (parsedDate == null) parsedDate = new Date(); + return new Date(parsedDate.getTime()); + } return null; } @@ -406,6 +443,17 @@ public final class httpHeader extends TreeMap implements Map { return headerDate(httpHeader.IF_MODIFIED_SINCE); } + public Object ifRange() { + if (containsKey(httpHeader.IF_RANGE)) { + try { + Date rangeDate = parseHTTPDate((String) get(httpHeader.IF_RANGE),false); + if (rangeDate != null) return new Date(rangeDate.getTime()); + } catch (Exception e) {} + return get(httpHeader.IF_RANGE); + } + return null; + } + public long age() { Date lm = lastModified(); Date sd = date(); diff --git a/source/de/anomic/http/httpdProxyHandler.java b/source/de/anomic/http/httpdProxyHandler.java index a0530bf64..53225857e 100644 --- a/source/de/anomic/http/httpdProxyHandler.java +++ b/source/de/anomic/http/httpdProxyHandler.java @@ -529,6 +529,9 @@ public final class httpdProxyHandler extends httpdAbstractHandler implements htt // removing hop by hop headers this.removeHopByHopHeaders(requestHeader); + // adding additional headers + setViaHeader(requestHeader, httpVer); + // send request res = remote.GET(remotePath, requestHeader); conProp.put(httpHeader.CONNECTION_PROP_CLIENT_REQUEST_HEADER,requestHeader); @@ -555,7 +558,7 @@ public final class httpdProxyHandler extends httpdAbstractHandler implements htt } res.responseHeader.remove(httpHeader.CONTENT_LENGTH); } - } + } // if (((String)requestHeader.get(httpHeader.ACCEPT_ENCODING,"")).indexOf("gzip") != -1) { // zipped = new GZIPOutputStream((chunked != null) ? chunked : respond); @@ -606,6 +609,9 @@ public final class httpdProxyHandler extends httpdAbstractHandler implements htt // remove hop by hop headers this.removeHopByHopHeaders(res.responseHeader); + // adding additional headers + setViaHeader(res.responseHeader, res.httpVer); + // sending the respond header back to the client if (chunkedOut != null) { res.responseHeader.put(httpHeader.TRANSFER_ENCODING, "chunked"); @@ -731,6 +737,9 @@ public final class httpdProxyHandler extends httpdAbstractHandler implements htt // remove hop by hop headers this.removeHopByHopHeaders(cachedResponseHeader); + // adding additional headers + setViaHeader(cachedResponseHeader, httpVer); + // replace date field in old header by actual date, this is according to RFC cachedResponseHeader.put(httpHeader.DATE, httpc.dateString(httpc.nowDate())); @@ -909,6 +918,9 @@ public final class httpdProxyHandler extends httpdAbstractHandler implements htt // removing hop by hop headers this.removeHopByHopHeaders(requestHeader); + + // adding outgoing headers + setViaHeader(requestHeader, httpVer); // open the connection: second is needed for [AS] patch remote = (yAddress == null) ? newhttpc(host, port, timeout): newhttpc(yAddress, timeout); @@ -924,6 +936,9 @@ public final class httpdProxyHandler extends httpdAbstractHandler implements htt // removing hop by hop headers this.removeHopByHopHeaders(res.responseHeader); + // adding outgoing headers + setViaHeader(res.responseHeader, res.httpVer); + // sending the server respond back to the client httpd.sendRespondHeader(conProp,respond,httpVer,res.statusCode,res.statusText,res.responseHeader); } catch (Exception e) { @@ -995,6 +1010,9 @@ public final class httpdProxyHandler extends httpdAbstractHandler implements htt // removing hop by hop headers this.removeHopByHopHeaders(requestHeader); + // adding additional headers + setViaHeader(requestHeader, httpVer); + // sending the request remote = (yAddress == null) ? newhttpc(host, port, timeout) : newhttpc(yAddress, timeout); httpc.response res = remote.POST(remotePath, requestHeader, body); @@ -1027,6 +1045,9 @@ public final class httpdProxyHandler extends httpdAbstractHandler implements htt // remove hop by hop headers this.removeHopByHopHeaders(res.responseHeader); + // adding additional headers + setViaHeader(res.responseHeader, res.httpVer); + // sending the respond header back to the client if (chunked != null) { res.responseHeader.put(httpHeader.TRANSFER_ENCODING, "chunked"); @@ -1485,6 +1506,24 @@ public final class httpdProxyHandler extends httpdAbstractHandler implements htt return this.userAgentStr.toString(); } + private void setViaHeader(httpHeader header, String httpVer) { + if (!switchboard.getConfigBool("proxy.sendViaHeader", true)) return; + + // getting header set by other proxies in the chain + StringBuffer viaValue = new StringBuffer(); + if (header.containsKey(httpHeader.VIA)) viaValue.append((String)header.get(httpHeader.VIA)); + if (viaValue.length() > 0) viaValue.append(", "); + + // appending info about this peer + viaValue + .append(httpVer).append(" ") + .append(yacyCore.seedDB.mySeed.getName()).append(".yacy ") + .append("(YaCy ").append(switchboard.getConfig("vString", "0.0")).append(")"); + + // storing header back + header.put(httpHeader.VIA, viaValue.toString()); + } + /** * This function is used to generate a logging message according to the * squid logging format.

diff --git a/source/de/anomic/server/serverAbstractSwitch.java b/source/de/anomic/server/serverAbstractSwitch.java index 911cb8ea6..515f12b0b 100644 --- a/source/de/anomic/server/serverAbstractSwitch.java +++ b/source/de/anomic/server/serverAbstractSwitch.java @@ -217,6 +217,10 @@ public abstract class serverAbstractSwitch implements serverSwitch { return dflt; } } + + public boolean getConfigBool(String key, boolean dflt) { + return Boolean.valueOf(getConfig(key, Boolean.toString(dflt))).booleanValue(); + } public Iterator configKeys() { return configProps.keySet().iterator(); diff --git a/yacy.init b/yacy.init index 6aef05c16..e103079bb 100644 --- a/yacy.init +++ b/yacy.init @@ -534,6 +534,9 @@ isTransparentProxy=false # Specifies if yacy should use the http connection keep-alive feature connectionKeepAliveSupport=true +# Specifies if the proxy should send the via header according to RFC +proxy.sendViaHeader=true + # Configuration options needed to configure server port forwarding portForwardingEnabled=false portForwardingUseProxy=false