Skip to content

Commit

Permalink
Merge pull request #216 from RAVEENSR/master
Browse files Browse the repository at this point in the history
Fix not honouring the non Proxy ports
  • Loading branch information
Lakshitha Gunasekara authored Nov 5, 2020
2 parents 78cb059 + af3ac87 commit 9cdb6ea
Showing 1 changed file with 202 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
Expand Down Expand Up @@ -66,6 +67,9 @@ public class XMLHttpRequestHostObject extends ScriptableObject {
private Function onreadystatechange;

private static final String hostObjectName = "XMLHttpRequest";
protected static final String HTTP_PROXY_HOST = "http.proxyHost";
protected static final String HTTP_PROXY_PORT = "http.proxyPort";
protected static final String HTTP_NON_PROXY_HOSTS = "http.nonProxyHosts";

private Context context = null;

Expand All @@ -91,10 +95,6 @@ public class XMLHttpRequestHostObject extends ScriptableObject {

public XMLHttpRequestHostObject() {
httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
ProxyHost proxyConfig = getProxyConfig();
if (proxyConfig != null) {
httpClient.getHostConfiguration().setProxyHost(proxyConfig);
}
}

@Override
Expand Down Expand Up @@ -552,6 +552,9 @@ public Object call() throws Exception {

private static void executeRequest(Context cx, XMLHttpRequestHostObject xhr) throws ScriptException {
try {
String host = xhr.method.getURI().getHost();
ProxyHost proxyHost = getProxyConfig(host);
xhr.httpClient.getHostConfiguration().setProxyHost(proxyHost);
xhr.httpClient.executeMethod(xhr.method);
xhr.statusLine = xhr.method.getStatusLine();
xhr.responseHeaders = xhr.method.getResponseHeaders();
Expand Down Expand Up @@ -594,12 +597,17 @@ private static boolean isInvalidHeader(String header) {
return false;
}

private ProxyHost getProxyConfig() {
private static ProxyHost getProxyConfig(String host) {

ProxyHost proxyConfig = null;

String proxyHost = System.getProperty("http.proxyHost");
String proxyPortStr = System.getProperty("http.proxyPort");
String proxyHost = System.getProperty(HTTP_PROXY_HOST);
String proxyPortStr = System.getProperty(HTTP_PROXY_PORT);
String nonProxyHosts = System.getProperty(HTTP_NON_PROXY_HOSTS);

if (isHostInNonProxyList(host, nonProxyHosts)) {
return null;
}

int proxyPort = -1;
if (proxyHost != null) {
Expand All @@ -621,4 +629,190 @@ private ProxyHost getProxyConfig() {
return proxyConfig;
}

}
/**
* Check if the specified host is in the list of non proxy hosts.
*
* @param host host name
* @param nonProxyHosts string containing the list of non proxy hosts
* @return true/false
*/
public static boolean isHostInNonProxyList(String host, String nonProxyHosts) {
if ((nonProxyHosts == null) || (host == null)) {
return false;
}

/*
* The http.nonProxyHosts system property is a list enclosed in
* double quotes with items separated by a vertical bar.
*/
StringTokenizer tokenizer = new StringTokenizer(nonProxyHosts, "|\"");

while (tokenizer.hasMoreTokens()) {
String pattern = tokenizer.nextToken();
if (match(pattern, host, false)) {
return true;
}
}
return false;
}

/**
* Matches a string against a pattern. The pattern contains two special
* characters:
* '*' which means zero or more characters,
*
* @param pattern the (non-null) pattern to match against
* @param str the (non-null) string that must be matched against the
* pattern
* @param isCaseSensitive
* @return <code>true</code> when the string matches against the pattern,
* <code>false</code> otherwise.
*/
private static boolean match(String pattern, String str, boolean isCaseSensitive) {

char[] patArr = pattern.toCharArray();
char[] strArr = str.toCharArray();
int patIdxStart = 0;
int patIdxEnd = patArr.length - 1;
int strIdxStart = 0;
int strIdxEnd = strArr.length - 1;
char ch;
boolean containsStar = false;

for (int i = 0; i < patArr.length; i++) {
if (patArr[i] == '*') {
containsStar = true;
break;
}
}
if (!containsStar) {

// No '*'s, so we make a shortcut
if (patIdxEnd != strIdxEnd) {
return false; // Pattern and string do not have the same size
}
for (int i = 0; i <= patIdxEnd; i++) {
ch = patArr[i];
if (isCaseSensitive && (ch != strArr[i])) {
return false; // Character mismatch
}
if (!isCaseSensitive
&& (Character.toUpperCase(ch)
!= Character.toUpperCase(strArr[i]))) {
return false; // Character mismatch
}
}
return true; // String matches against pattern
}
if (patIdxEnd == 0) {
return true; // Pattern contains only '*', which matches anything
}

// Process characters before first star
while ((ch = patArr[patIdxStart]) != '*' && (strIdxStart <= strIdxEnd)) {
if (isCaseSensitive && (ch != strArr[strIdxStart])) {
return false; // Character mismatch
}
if (!isCaseSensitive
&& (Character.toUpperCase(ch)
!= Character.toUpperCase(strArr[strIdxStart]))) {
return false; // Character mismatch
}
patIdxStart++;
strIdxStart++;
}
if (strIdxStart > strIdxEnd) {

// All characters in the string are used. Check if only '*'s are
// left in the pattern. If so, we succeeded. Otherwise failure.
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}

// Process characters after last star
while ((ch = patArr[patIdxEnd]) != '*' && (strIdxStart <= strIdxEnd)) {
if (isCaseSensitive && (ch != strArr[strIdxEnd])) {
return false; // Character mismatch
}
if (!isCaseSensitive
&& (Character.toUpperCase(ch)
!= Character.toUpperCase(strArr[strIdxEnd]))) {
return false; // Character mismatch
}
patIdxEnd--;
strIdxEnd--;
}
if (strIdxStart > strIdxEnd) {

// All characters in the string are used. Check if only '*'s are
// left in the pattern. If so, we succeeded. Otherwise failure.
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}

// process pattern between stars. padIdxStart and patIdxEnd point
// always to a '*'.
while ((patIdxStart != patIdxEnd) && (strIdxStart <= strIdxEnd)) {
int patIdxTmp = -1;

for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
if (patArr[i] == '*') {
patIdxTmp = i;
break;
}
}
if (patIdxTmp == patIdxStart + 1) {

// Two stars next to each other, skip the first one.
patIdxStart++;
continue;
}

// Find the pattern between padIdxStart & padIdxTmp in str between
// strIdxStart & strIdxEnd
int patLength = (patIdxTmp - patIdxStart - 1);
int strLength = (strIdxEnd - strIdxStart + 1);
int foundIdx = -1;

strLoop:
for (int i = 0; i <= strLength - patLength; i++) {
for (int j = 0; j < patLength; j++) {
ch = patArr[patIdxStart + j + 1];
if (isCaseSensitive
&& (ch != strArr[strIdxStart + i + j])) {
continue strLoop;
}
if (!isCaseSensitive && (Character
.toUpperCase(ch) != Character
.toUpperCase(strArr[strIdxStart + i + j]))) {
continue strLoop;
}
}
foundIdx = strIdxStart + i;
break;
}
if (foundIdx == -1) {
return false;
}
patIdxStart = patIdxTmp;
strIdxStart = foundIdx + patLength;
}

// All characters in the string are used. Check if only '*'s are left
// in the pattern. If so, we succeeded. Otherwise failure.
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
}

0 comments on commit 9cdb6ea

Please sign in to comment.