8170868: DefaultProxySelector should use system defaults on Windows, MacOS and Gnome
Reviewed-by: chegar, simonis, clanger, stuefe, erikj
This commit is contained in:
parent
64dd421a20
commit
4d92a188b2
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -44,8 +44,9 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBNET, \
|
||||
LIBS_linux := $(LIBDL) -lpthread, \
|
||||
LIBS_solaris := -lnsl -lsocket $(LIBDL) -lc, \
|
||||
LIBS_aix := $(LIBDL),\
|
||||
LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib \
|
||||
LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib winhttp.lib \
|
||||
delayimp.lib $(WIN_JAVA_LIB) advapi32.lib, \
|
||||
LIBS_macosx := -framework CoreFoundation -framework CoreServices, \
|
||||
VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
|
||||
RC_FLAGS := $(RC_FLAGS) \
|
||||
-D "JDK_FNAME=net.dll" \
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -97,7 +97,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_net_sdp_SdpSupport_convert0;
|
||||
Java_sun_net_sdp_SdpSupport_create0;
|
||||
Java_sun_net_spi_DefaultProxySelector_init;
|
||||
Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
|
||||
Java_sun_net_spi_DefaultProxySelector_getSystemProxies;
|
||||
NET_SockaddrToInetAddress;
|
||||
NET_SockaddrEqualsInetAddress;
|
||||
NET_InetAddressToSockaddr;
|
||||
|
284
jdk/src/java.base/macosx/native/libnet/DefaultProxySelector.c
Normal file
284
jdk/src/java.base/macosx/native/libnet/DefaultProxySelector.c
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jvm_md.h"
|
||||
|
||||
#include "proxy_util.h"
|
||||
|
||||
#include "sun_net_spi_DefaultProxySelector.h"
|
||||
|
||||
|
||||
/**
|
||||
* For more information on how to use the APIs in "CFProxySupport.h" see:
|
||||
* https://developer.apple.com/legacy/library/samplecode/CFProxySupportTool/Introduction/Intro.html
|
||||
*/
|
||||
|
||||
#define kResolveProxyRunLoopMode CFSTR("sun.net.spi.DefaultProxySelector")
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
/* Callback for CFNetworkExecuteProxyAutoConfigurationURL. */
|
||||
static void proxyUrlCallback(void * client, CFArrayRef proxies, CFErrorRef error) {
|
||||
/* client is a pointer to a CFTypeRef and holds either proxies or an error. */
|
||||
CFTypeRef* resultPtr = (CFTypeRef *)client;
|
||||
|
||||
if (error != NULL) {
|
||||
*resultPtr = CFRetain(error);
|
||||
} else {
|
||||
*resultPtr = CFRetain(proxies);
|
||||
}
|
||||
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a new array of proxies containing all the given non-PAC proxies as
|
||||
* well as the results of executing all the given PAC-based proxies, for the
|
||||
* specified URL. 'proxies' is a list that may contain both PAC and non-PAC
|
||||
* proxies.
|
||||
*/
|
||||
static CFArrayRef createExpandedProxiesArray(CFArrayRef proxies, CFURLRef url) {
|
||||
|
||||
CFIndex count;
|
||||
CFIndex index;
|
||||
CFMutableArrayRef expandedProxiesArray;
|
||||
|
||||
expandedProxiesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
|
||||
if (expandedProxiesArray == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Iterate over the array of proxies */
|
||||
count = CFArrayGetCount(proxies);
|
||||
for (index = 0; index < count ; index++) {
|
||||
CFDictionaryRef currentProxy;
|
||||
CFStringRef proxyType;
|
||||
|
||||
currentProxy = (CFDictionaryRef) CFArrayGetValueAtIndex(proxies, index);
|
||||
if(currentProxy == NULL) {
|
||||
CFRelease(expandedProxiesArray);
|
||||
return NULL;
|
||||
}
|
||||
proxyType = (CFStringRef) CFDictionaryGetValue(currentProxy, kCFProxyTypeKey);
|
||||
if (proxyType == NULL) {
|
||||
CFRelease(expandedProxiesArray);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!CFEqual(proxyType, kCFProxyTypeAutoConfigurationURL)) {
|
||||
/* Non-PAC entry, just copy it to the new array */
|
||||
CFArrayAppendValue(expandedProxiesArray, currentProxy);
|
||||
} else {
|
||||
/* PAC-based URL, execute its script append its results */
|
||||
CFRunLoopSourceRef runLoop;
|
||||
CFURLRef scriptURL;
|
||||
CFTypeRef result = NULL;
|
||||
CFStreamClientContext context = { 0, &result, NULL, NULL, NULL };
|
||||
CFTimeInterval timeout = 5;
|
||||
|
||||
scriptURL = CFDictionaryGetValue(currentProxy, kCFProxyAutoConfigurationURLKey);
|
||||
|
||||
runLoop = CFNetworkExecuteProxyAutoConfigurationURL(scriptURL, url, proxyUrlCallback,
|
||||
&context);
|
||||
if (runLoop != NULL) {
|
||||
/*
|
||||
* Despite the fact that CFNetworkExecuteProxyAutoConfigurationURL has
|
||||
* neither a "Create" nor a "Copy" in the name, we are required to
|
||||
* release the return CFRunLoopSourceRef <rdar://problem/5533931>.
|
||||
*/
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoop, kResolveProxyRunLoopMode);
|
||||
CFRunLoopRunInMode(kResolveProxyRunLoopMode, timeout, false);
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoop, kResolveProxyRunLoopMode);
|
||||
|
||||
/*
|
||||
* Once the runloop returns, there will be either an error result or
|
||||
* a proxies array result. Do the appropriate thing with that result.
|
||||
*/
|
||||
if (result != NULL) {
|
||||
if (CFGetTypeID(result) == CFArrayGetTypeID()) {
|
||||
/*
|
||||
* Append the new array from the PAC list - it contains
|
||||
* only non-PAC entries.
|
||||
*/
|
||||
CFArrayAppendArray(expandedProxiesArray, result,
|
||||
CFRangeMake(0, CFArrayGetCount(result)));
|
||||
}
|
||||
CFRelease(result);
|
||||
}
|
||||
CFRelease(runLoop);
|
||||
}
|
||||
}
|
||||
}
|
||||
return expandedProxiesArray;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_net_spi_DefaultProxySelector
|
||||
* Method: init
|
||||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
|
||||
if (!initJavaClass(env)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_net_spi_DefaultProxySelector
|
||||
* Method: getSystemProxies
|
||||
* Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
|
||||
jobject this,
|
||||
jstring proto,
|
||||
jstring host)
|
||||
{
|
||||
CFDictionaryRef proxyDicRef = NULL;
|
||||
CFURLRef urlRef = NULL;
|
||||
bool proxyFound = false;
|
||||
jobjectArray proxyArray = NULL;
|
||||
const char *cproto;
|
||||
const char *chost;
|
||||
|
||||
/* Get system proxy settings */
|
||||
proxyDicRef = CFNetworkCopySystemProxySettings();
|
||||
if (proxyDicRef == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create CFURLRef from proto and host */
|
||||
cproto = (*env)->GetStringUTFChars(env, proto, NULL);
|
||||
if (cproto != NULL) {
|
||||
chost = (*env)->GetStringUTFChars(env, host, NULL);
|
||||
if (chost != NULL) {
|
||||
char* uri = NULL;
|
||||
size_t protoLen = 0;
|
||||
size_t hostLen = 0;
|
||||
|
||||
protoLen = strlen(cproto);
|
||||
hostLen = strlen(chost);
|
||||
|
||||
/* Construct the uri, cproto + "://" + chost */
|
||||
uri = malloc(protoLen + hostLen + 4);
|
||||
if (uri != NULL) {
|
||||
memcpy(uri, cproto, protoLen);
|
||||
memcpy(uri + protoLen, "://", 3);
|
||||
memcpy(uri + protoLen + 3, chost, hostLen + 1);
|
||||
|
||||
urlRef = CFURLCreateWithBytes(NULL, (const UInt8 *) uri, strlen(uri),
|
||||
kCFStringEncodingUTF8, NULL);
|
||||
free(uri);
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars(env, host, chost);
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars(env, proto, cproto);
|
||||
}
|
||||
if (urlRef != NULL) {
|
||||
CFArrayRef urlProxyArrayRef = CFNetworkCopyProxiesForURL(urlRef, proxyDicRef);
|
||||
if (urlProxyArrayRef != NULL) {
|
||||
CFIndex count;
|
||||
CFIndex index;
|
||||
|
||||
CFArrayRef expandedProxyArray = createExpandedProxiesArray(urlProxyArrayRef, urlRef);
|
||||
CFRelease(urlProxyArrayRef);
|
||||
|
||||
if (expandedProxyArray == NULL) {
|
||||
CFRelease(urlRef);
|
||||
CFRelease(proxyDicRef);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = CFArrayGetCount(expandedProxyArray);
|
||||
|
||||
proxyArray = (*env)->NewObjectArray(env, count, proxy_class, NULL);
|
||||
if (proxyArray != NULL || (*env)->ExceptionCheck(env)) {
|
||||
/* Iterate over the expanded array of proxies */
|
||||
for (index = 0; index < count ; index++) {
|
||||
CFDictionaryRef currentProxy;
|
||||
CFStringRef proxyType;
|
||||
jobject proxy = NULL;
|
||||
|
||||
currentProxy = (CFDictionaryRef) CFArrayGetValueAtIndex(expandedProxyArray,
|
||||
index);
|
||||
proxyType = (CFStringRef) CFDictionaryGetValue(currentProxy, kCFProxyTypeKey);
|
||||
if (CFEqual(proxyType, kCFProxyTypeNone)) {
|
||||
/* This entry states no proxy, therefore just add a NO_PROXY object. */
|
||||
proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID);
|
||||
} else {
|
||||
/*
|
||||
* Create a proxy object for this entry.
|
||||
* Differentiate between SOCKS and HTTP type.
|
||||
*/
|
||||
jfieldID typeID = ptype_httpID;
|
||||
if (CFEqual(proxyType, kCFProxyTypeSOCKS)) {
|
||||
typeID = ptype_socksID;
|
||||
}
|
||||
CFNumberRef portNumberRef = (CFNumberRef)CFDictionaryGetValue(currentProxy,
|
||||
(const void*)kCFProxyPortNumberKey);
|
||||
if (portNumberRef != NULL) {
|
||||
int port = 0;
|
||||
if (CFNumberGetValue(portNumberRef, kCFNumberSInt32Type, &port)) {
|
||||
CFStringRef hostNameRef = (CFStringRef)CFDictionaryGetValue(
|
||||
currentProxy, (const void*)kCFProxyHostNameKey);
|
||||
if (hostNameRef != NULL) {
|
||||
char hostNameBuffer[BUFFER_SIZE];
|
||||
if (CFStringGetCString(hostNameRef, hostNameBuffer,
|
||||
BUFFER_SIZE, kCFStringEncodingUTF8)) {
|
||||
proxy = createProxy(env, typeID, &hostNameBuffer[0], port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (proxy == NULL || (*env)->ExceptionCheck(env)) {
|
||||
proxyArray = NULL;
|
||||
break;
|
||||
}
|
||||
(*env)->SetObjectArrayElement(env, proxyArray, index, proxy);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
proxyArray = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
CFRelease(expandedProxyArray);
|
||||
}
|
||||
CFRelease(urlRef);
|
||||
}
|
||||
CFRelease(proxyDicRef);
|
||||
|
||||
return proxyArray;
|
||||
}
|
@ -149,7 +149,7 @@ of proxies.</P>
|
||||
the <B>user.name</B> property will be used with no password.</P>
|
||||
</UL>
|
||||
<LI><P><B>java.net.useSystemProxies</B> (default: false)<BR>
|
||||
On recent Windows systems and on Gnome 2.x systems it is possible to
|
||||
On Windows systems, macOS systems and on Gnome systems it is possible to
|
||||
tell the java.net stack, setting this property to <B>true</B>, to use
|
||||
the system proxy settings (both these systems let you set proxies
|
||||
globally through their user interface). Note that this property is
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,16 +30,19 @@ import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
import sun.net.NetProperties;
|
||||
import sun.net.SocksProxy;
|
||||
import static java.util.regex.Pattern.quote;
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
/**
|
||||
* Supports proxy settings using system properties This proxy selector
|
||||
@ -87,6 +90,8 @@ public class DefaultProxySelector extends ProxySelector {
|
||||
|
||||
private static boolean hasSystemProxies = false;
|
||||
|
||||
private static final List<Proxy> NO_PROXY_LIST = List.of(Proxy.NO_PROXY);
|
||||
|
||||
static {
|
||||
final String key = "java.net.useSystemProxies";
|
||||
Boolean b = AccessController.doPrivileged(
|
||||
@ -149,8 +154,9 @@ public class DefaultProxySelector extends ProxySelector {
|
||||
* select() method. Where all the hard work is done.
|
||||
* Build a list of proxies depending on URI.
|
||||
* Since we're only providing compatibility with the system properties
|
||||
* from previous releases (see list above), that list will always
|
||||
* contain 1 single proxy, default being NO_PROXY.
|
||||
* from previous releases (see list above), that list will typically
|
||||
* contain one single proxy, default being NO_PROXY.
|
||||
* If we can get a system proxy it might contain more entries.
|
||||
*/
|
||||
public java.util.List<Proxy> select(URI uri) {
|
||||
if (uri == null) {
|
||||
@ -185,7 +191,6 @@ public class DefaultProxySelector extends ProxySelector {
|
||||
if (protocol == null || host == null) {
|
||||
throw new IllegalArgumentException("protocol = "+protocol+" host = "+host);
|
||||
}
|
||||
List<Proxy> proxyl = new ArrayList<Proxy>(1);
|
||||
|
||||
NonProxyInfo pinfo = null;
|
||||
|
||||
@ -214,9 +219,9 @@ public class DefaultProxySelector extends ProxySelector {
|
||||
* System properties it does help having only 1 call to doPrivileged.
|
||||
* Be mindful what you do in here though!
|
||||
*/
|
||||
Proxy p = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Proxy>() {
|
||||
public Proxy run() {
|
||||
Proxy[] proxyArray = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Proxy[]>() {
|
||||
public Proxy[] run() {
|
||||
int i, j;
|
||||
String phost = null;
|
||||
int pport = 0;
|
||||
@ -239,8 +244,8 @@ public class DefaultProxySelector extends ProxySelector {
|
||||
/**
|
||||
* No system property defined for that
|
||||
* protocol. Let's check System Proxy
|
||||
* settings (Gnome & Windows) if we were
|
||||
* instructed to.
|
||||
* settings (Gnome, MacOsX & Windows) if
|
||||
* we were instructed to.
|
||||
*/
|
||||
if (hasSystemProxies) {
|
||||
String sproto;
|
||||
@ -248,12 +253,9 @@ public class DefaultProxySelector extends ProxySelector {
|
||||
sproto = "socks";
|
||||
else
|
||||
sproto = proto;
|
||||
Proxy sproxy = getSystemProxy(sproto, urlhost);
|
||||
if (sproxy != null) {
|
||||
return sproxy;
|
||||
}
|
||||
return getSystemProxies(sproto, urlhost);
|
||||
}
|
||||
return Proxy.NO_PROXY;
|
||||
return null;
|
||||
}
|
||||
// If a Proxy Host is defined for that protocol
|
||||
// Let's get the NonProxyHosts property
|
||||
@ -281,7 +283,7 @@ public class DefaultProxySelector extends ProxySelector {
|
||||
}
|
||||
}
|
||||
if (shouldNotUseProxyFor(nprop.pattern, urlhost)) {
|
||||
return Proxy.NO_PROXY;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -311,22 +313,24 @@ public class DefaultProxySelector extends ProxySelector {
|
||||
saddr = InetSocketAddress.createUnresolved(phost, pport);
|
||||
// Socks is *always* the last on the list.
|
||||
if (j == (props[i].length - 1)) {
|
||||
return SocksProxy.create(saddr, socksProxyVersion());
|
||||
} else {
|
||||
return new Proxy(Proxy.Type.HTTP, saddr);
|
||||
return new Proxy[] {SocksProxy.create(saddr, socksProxyVersion())};
|
||||
}
|
||||
return new Proxy[] {new Proxy(Proxy.Type.HTTP, saddr)};
|
||||
}
|
||||
}
|
||||
return Proxy.NO_PROXY;
|
||||
return null;
|
||||
}});
|
||||
|
||||
proxyl.add(p);
|
||||
|
||||
/*
|
||||
* If no specific property was set for that URI, we should be
|
||||
* returning an iterator to an empty List.
|
||||
*/
|
||||
return proxyl;
|
||||
if (proxyArray != null) {
|
||||
// Remove duplicate entries, while preserving order.
|
||||
return Stream.of(proxyArray).distinct().collect(
|
||||
collectingAndThen(toList(), Collections::unmodifiableList));
|
||||
}
|
||||
|
||||
// If no specific proxy was found, return a standard list containing
|
||||
// only one NO_PROXY entry.
|
||||
return NO_PROXY_LIST;
|
||||
}
|
||||
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
|
||||
@ -354,7 +358,7 @@ public class DefaultProxySelector extends ProxySelector {
|
||||
}
|
||||
|
||||
private static native boolean init();
|
||||
private synchronized native Proxy getSystemProxy(String protocol, String host);
|
||||
private synchronized native Proxy[] getSystemProxies(String protocol, String host);
|
||||
|
||||
/**
|
||||
* @return {@code true} if given this pattern for non-proxy hosts and this
|
||||
|
101
jdk/src/java.base/share/native/libnet/proxy_util.c
Normal file
101
jdk/src/java.base/share/native/libnet/proxy_util.c
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
|
||||
#include "proxy_util.h"
|
||||
|
||||
jclass proxy_class;
|
||||
jclass isaddr_class;
|
||||
jclass ptype_class;
|
||||
jmethodID isaddr_createUnresolvedID;
|
||||
jmethodID proxy_ctrID;
|
||||
jfieldID pr_no_proxyID;
|
||||
jfieldID ptype_httpID;
|
||||
jfieldID ptype_socksID;
|
||||
|
||||
int initJavaClass(JNIEnv *env) {
|
||||
jclass proxy_cls = NULL;
|
||||
jclass ptype_cls = NULL;
|
||||
jclass isaddr_cls = NULL;
|
||||
|
||||
// Proxy initialization
|
||||
proxy_cls = (*env)->FindClass(env,"java/net/Proxy");
|
||||
CHECK_NULL_RETURN(proxy_cls, 0);
|
||||
proxy_class = (*env)->NewGlobalRef(env, proxy_cls);
|
||||
CHECK_NULL_RETURN(proxy_class, 0);
|
||||
proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>",
|
||||
"(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
|
||||
CHECK_NULL_RETURN(proxy_ctrID, 0);
|
||||
|
||||
// Proxy$Type initialization
|
||||
ptype_cls = (*env)->FindClass(env,"java/net/Proxy$Type");
|
||||
CHECK_NULL_RETURN(ptype_cls, 0);
|
||||
ptype_class = (*env)->NewGlobalRef(env, ptype_cls);
|
||||
CHECK_NULL_RETURN(ptype_class, 0);
|
||||
ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP",
|
||||
"Ljava/net/Proxy$Type;");
|
||||
CHECK_NULL_RETURN(ptype_httpID, 0);
|
||||
ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS",
|
||||
"Ljava/net/Proxy$Type;");
|
||||
CHECK_NULL_RETURN(ptype_socksID, 0);
|
||||
|
||||
// NO_PROXY
|
||||
pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY",
|
||||
"Ljava/net/Proxy;");
|
||||
CHECK_NULL_RETURN(pr_no_proxyID, 0);
|
||||
|
||||
// InetSocketAddress initialization
|
||||
isaddr_cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
|
||||
CHECK_NULL_RETURN(isaddr_cls, 0);
|
||||
isaddr_class = (*env)->NewGlobalRef(env, isaddr_cls);
|
||||
CHECK_NULL_RETURN(isaddr_class, 0);
|
||||
isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class,
|
||||
"createUnresolved",
|
||||
"(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
|
||||
|
||||
return isaddr_createUnresolvedID != NULL ? 1 : 0;
|
||||
}
|
||||
|
||||
jobject createProxy(JNIEnv *env, jfieldID ptype_ID, const char* phost, unsigned short pport) {
|
||||
jobject jProxy = NULL;
|
||||
jobject type_proxy = NULL;
|
||||
type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_ID);
|
||||
if (type_proxy) {
|
||||
jstring jhost = NULL;
|
||||
jhost = (*env)->NewStringUTF(env, phost);
|
||||
if (jhost) {
|
||||
jobject isa = NULL;
|
||||
isa = (*env)->CallStaticObjectMethod(env, isaddr_class,
|
||||
isaddr_createUnresolvedID, jhost, pport);
|
||||
if (isa) {
|
||||
jProxy = (*env)->NewObject(env, proxy_class, proxy_ctrID,
|
||||
type_proxy, isa);
|
||||
}
|
||||
}
|
||||
}
|
||||
return jProxy;
|
||||
}
|
37
jdk/src/java.base/share/native/libnet/proxy_util.h
Normal file
37
jdk/src/java.base/share/native/libnet/proxy_util.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
extern jclass proxy_class;
|
||||
extern jclass isaddr_class;
|
||||
extern jclass ptype_class;
|
||||
extern jmethodID isaddr_createUnresolvedID;
|
||||
extern jmethodID proxy_ctrID;
|
||||
extern jfieldID pr_no_proxyID;
|
||||
extern jfieldID ptype_httpID;
|
||||
extern jfieldID ptype_socksID;
|
||||
|
||||
int initJavaClass(JNIEnv *env);
|
||||
|
||||
jobject createProxy(JNIEnv *env, jfieldID ptype_ID, const char* phost, unsigned short pport);
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,24 +23,20 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jvm_md.h"
|
||||
#include "jlong.h"
|
||||
#include "sun_net_spi_DefaultProxySelector.h"
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_NULL_RETURN
|
||||
#define CHECK_NULL_RETURN(x, y) if ((x) == NULL) return y;
|
||||
#endif
|
||||
#include "proxy_util.h"
|
||||
|
||||
#include "sun_net_spi_DefaultProxySelector.h"
|
||||
|
||||
|
||||
/**
|
||||
* These functions are used by the sun.net.spi.DefaultProxySelector class
|
||||
@ -112,43 +108,11 @@ static g_network_address_get_hostname_func* g_network_address_get_hostname = NUL
|
||||
static g_network_address_get_port_func* g_network_address_get_port = NULL;
|
||||
static g_strfreev_func* g_strfreev = NULL;
|
||||
|
||||
|
||||
static jclass proxy_class;
|
||||
static jclass isaddr_class;
|
||||
static jclass ptype_class;
|
||||
static jmethodID isaddr_createUnresolvedID;
|
||||
static jmethodID proxy_ctrID;
|
||||
static jfieldID ptype_httpID;
|
||||
static jfieldID ptype_socksID;
|
||||
|
||||
|
||||
static void* gconf_client = NULL;
|
||||
static int use_gproxyResolver = 0;
|
||||
static int use_gconf = 0;
|
||||
|
||||
|
||||
static jobject createProxy(JNIEnv *env, jfieldID ptype_ID,
|
||||
const char* phost, unsigned short pport)
|
||||
{
|
||||
jobject jProxy = NULL;
|
||||
jobject type_proxy = NULL;
|
||||
type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_ID);
|
||||
if (type_proxy) {
|
||||
jstring jhost = NULL;
|
||||
jhost = (*env)->NewStringUTF(env, phost);
|
||||
if (jhost) {
|
||||
jobject isa = NULL;
|
||||
isa = (*env)->CallStaticObjectMethod(env, isaddr_class,
|
||||
isaddr_createUnresolvedID, jhost, pport);
|
||||
if (isa) {
|
||||
jProxy = (*env)->NewObject(env, proxy_class, proxy_ctrID,
|
||||
type_proxy, isa);
|
||||
}
|
||||
}
|
||||
}
|
||||
return jProxy;
|
||||
}
|
||||
|
||||
static int initGConf() {
|
||||
/**
|
||||
* Let's try to load GConf-2 library
|
||||
@ -196,18 +160,18 @@ static int initGConf() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static jobject getProxyByGConf(JNIEnv *env, const char* cproto,
|
||||
const char* chost)
|
||||
static jobjectArray getProxyByGConf(JNIEnv *env, const char* cproto,
|
||||
const char* chost)
|
||||
{
|
||||
char *phost = NULL;
|
||||
char *mode = NULL;
|
||||
int pport = 0;
|
||||
int use_proxy = 0;
|
||||
int use_same_proxy = 0;
|
||||
jobject proxy = NULL;
|
||||
jobjectArray proxy_array = NULL;
|
||||
jfieldID ptype_ID = ptype_httpID;
|
||||
|
||||
// We only check manual proxy configurations
|
||||
/* We only check manual proxy configurations */
|
||||
mode = (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
|
||||
if (mode && !strcasecmp(mode, "manual")) {
|
||||
/*
|
||||
@ -293,7 +257,7 @@ static jobject getProxyByGConf(JNIEnv *env, const char* cproto,
|
||||
char *s;
|
||||
|
||||
/**
|
||||
* check for the exclude list (aka "No Proxy For" list).
|
||||
* Check for the exclude list (aka "No Proxy For" list).
|
||||
* It's a list of comma separated suffixes (e.g. domain name).
|
||||
*/
|
||||
noproxyfor = (*my_get_string_func)(gconf_client, "/system/proxy/no_proxy_for", NULL);
|
||||
@ -313,11 +277,25 @@ static jobject getProxyByGConf(JNIEnv *env, const char* cproto,
|
||||
s = strtok_r(NULL, ", ", tmpbuf);
|
||||
}
|
||||
}
|
||||
if (use_proxy)
|
||||
if (use_proxy) {
|
||||
jobject proxy = NULL;
|
||||
/* create a proxy array with one element. */
|
||||
proxy_array = (*env)->NewObjectArray(env, 1, proxy_class, NULL);
|
||||
if (proxy_array == NULL || (*env)->ExceptionCheck(env)) {
|
||||
return NULL;
|
||||
}
|
||||
proxy = createProxy(env, ptype_ID, phost, pport);
|
||||
if (proxy == NULL || (*env)->ExceptionCheck(env)) {
|
||||
return NULL;
|
||||
}
|
||||
(*env)->SetObjectArrayElement(env, proxy_array, 0, proxy);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return proxy;
|
||||
return proxy_array;
|
||||
}
|
||||
|
||||
static int initGProxyResolver() {
|
||||
@ -371,8 +349,8 @@ static int initGProxyResolver() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static jobject getProxyByGProxyResolver(JNIEnv *env, const char* cproto,
|
||||
const char* chost)
|
||||
static jobjectArray getProxyByGProxyResolver(JNIEnv *env, const char *cproto,
|
||||
const char *chost)
|
||||
{
|
||||
GProxyResolver* resolver = NULL;
|
||||
char** proxies = NULL;
|
||||
@ -382,19 +360,19 @@ static jobject getProxyByGProxyResolver(JNIEnv *env, const char* cproto,
|
||||
size_t hostLen = 0;
|
||||
char* uri = NULL;
|
||||
|
||||
jobject jProxy = NULL;
|
||||
jobjectArray proxy_array = NULL;
|
||||
|
||||
resolver = (*g_proxy_resolver_get_default)();
|
||||
if (resolver == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Construct the uri, cproto + "://" + chost
|
||||
/* Construct the uri, cproto + "://" + chost */
|
||||
protoLen = strlen(cproto);
|
||||
hostLen = strlen(chost);
|
||||
uri = malloc(protoLen + hostLen + 4);
|
||||
if (!uri) {
|
||||
// Out of memory
|
||||
/* Out of memory */
|
||||
return NULL;
|
||||
}
|
||||
memcpy(uri, cproto, protoLen);
|
||||
@ -414,22 +392,56 @@ static jobject getProxyByGProxyResolver(JNIEnv *env, const char* cproto,
|
||||
if (proxies) {
|
||||
if (!error) {
|
||||
int i;
|
||||
for(i = 0; proxies[i] && !jProxy; i++) {
|
||||
if (strcmp(proxies[i], "direct://")) {
|
||||
GSocketConnectable* conn =
|
||||
(*g_network_address_parse_uri)(proxies[i], 0,
|
||||
&error);
|
||||
if (conn && !error) {
|
||||
const char* phost = NULL;
|
||||
unsigned short pport = 0;
|
||||
phost = (*g_network_address_get_hostname)(conn);
|
||||
pport = (*g_network_address_get_port)(conn);
|
||||
if (phost && pport > 0) {
|
||||
jfieldID ptype_ID = ptype_httpID;
|
||||
if (!strncmp(proxies[i], "socks", 5))
|
||||
ptype_ID = ptype_socksID;
|
||||
int nr_proxies = 0;
|
||||
char** p = proxies;
|
||||
/* count the elements in the null terminated string vector. */
|
||||
while (*p) {
|
||||
nr_proxies++;
|
||||
p++;
|
||||
}
|
||||
/* create a proxy array that has to be filled. */
|
||||
proxy_array = (*env)->NewObjectArray(env, nr_proxies, proxy_class, NULL);
|
||||
if (proxy_array != NULL && !(*env)->ExceptionCheck(env)) {
|
||||
for (i = 0; proxies[i]; i++) {
|
||||
if (strncmp(proxies[i], "direct://", 9)) {
|
||||
GSocketConnectable* conn =
|
||||
(*g_network_address_parse_uri)(proxies[i], 0,
|
||||
&error);
|
||||
if (conn && !error) {
|
||||
const char *phost = NULL;
|
||||
unsigned short pport = 0;
|
||||
phost = (*g_network_address_get_hostname)(conn);
|
||||
pport = (*g_network_address_get_port)(conn);
|
||||
if (phost && pport > 0) {
|
||||
jobject proxy = NULL;
|
||||
jfieldID ptype_ID = ptype_httpID;
|
||||
if (!strncmp(proxies[i], "socks", 5))
|
||||
ptype_ID = ptype_socksID;
|
||||
|
||||
jProxy = createProxy(env, ptype_ID, phost, pport);
|
||||
proxy = createProxy(env, ptype_ID, phost, pport);
|
||||
if (proxy == NULL || (*env)->ExceptionCheck(env)) {
|
||||
proxy_array = NULL;
|
||||
break;
|
||||
}
|
||||
(*env)->SetObjectArrayElement(env, proxy_array, i, proxy);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
proxy_array = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* direct connection - no proxy */
|
||||
jobject proxy = (*env)->GetStaticObjectField(env, proxy_class,
|
||||
pr_no_proxyID);
|
||||
if (proxy == NULL || (*env)->ExceptionCheck(env)) {
|
||||
proxy_array = NULL;
|
||||
break;
|
||||
}
|
||||
(*env)->SetObjectArrayElement(env, proxy_array, i, proxy);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
proxy_array = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -438,48 +450,9 @@ static jobject getProxyByGProxyResolver(JNIEnv *env, const char* cproto,
|
||||
(*g_strfreev)(proxies);
|
||||
}
|
||||
|
||||
return jProxy;
|
||||
return proxy_array;
|
||||
}
|
||||
|
||||
static int initJavaClass(JNIEnv *env) {
|
||||
jclass proxy_cls = NULL;
|
||||
jclass ptype_cls = NULL;
|
||||
jclass isaddr_cls = NULL;
|
||||
|
||||
// Proxy initialization
|
||||
proxy_cls = (*env)->FindClass(env,"java/net/Proxy");
|
||||
CHECK_NULL_RETURN(proxy_cls, 0);
|
||||
proxy_class = (*env)->NewGlobalRef(env, proxy_cls);
|
||||
CHECK_NULL_RETURN(proxy_class, 0);
|
||||
proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>",
|
||||
"(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
|
||||
CHECK_NULL_RETURN(proxy_ctrID, 0);
|
||||
|
||||
// Proxy$Type initialization
|
||||
ptype_cls = (*env)->FindClass(env,"java/net/Proxy$Type");
|
||||
CHECK_NULL_RETURN(ptype_cls, 0);
|
||||
ptype_class = (*env)->NewGlobalRef(env, ptype_cls);
|
||||
CHECK_NULL_RETURN(ptype_class, 0);
|
||||
ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP",
|
||||
"Ljava/net/Proxy$Type;");
|
||||
CHECK_NULL_RETURN(ptype_httpID, 0);
|
||||
ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS",
|
||||
"Ljava/net/Proxy$Type;");
|
||||
CHECK_NULL_RETURN(ptype_socksID, 0);
|
||||
|
||||
// InetSocketAddress initialization
|
||||
isaddr_cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
|
||||
CHECK_NULL_RETURN(isaddr_cls, 0);
|
||||
isaddr_class = (*env)->NewGlobalRef(env, isaddr_cls);
|
||||
CHECK_NULL_RETURN(isaddr_class, 0);
|
||||
isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class,
|
||||
"createUnresolved",
|
||||
"(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
|
||||
|
||||
return isaddr_createUnresolvedID != NULL ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_net_spi_DefaultProxySelector
|
||||
* Method: init
|
||||
@ -500,14 +473,14 @@ Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
|
||||
|
||||
/*
|
||||
* Class: sun_net_spi_DefaultProxySelector
|
||||
* Method: getSystemProxy
|
||||
* Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;
|
||||
* Method: getSystemProxies
|
||||
* Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
|
||||
jobject this,
|
||||
jstring proto,
|
||||
jstring host)
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
|
||||
jobject this,
|
||||
jstring proto,
|
||||
jstring host)
|
||||
{
|
||||
const char* cproto;
|
||||
const char* chost;
|
||||
@ -515,7 +488,7 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
|
||||
jboolean isProtoCopy;
|
||||
jboolean isHostCopy;
|
||||
|
||||
jobject proxy = NULL;
|
||||
jobjectArray proxyArray = NULL;
|
||||
|
||||
cproto = (*env)->GetStringUTFChars(env, proto, &isProtoCopy);
|
||||
|
||||
@ -523,16 +496,15 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
|
||||
chost = (*env)->GetStringUTFChars(env, host, &isHostCopy);
|
||||
if (chost != NULL) {
|
||||
if (use_gproxyResolver)
|
||||
proxy = getProxyByGProxyResolver(env, cproto, chost);
|
||||
proxyArray = getProxyByGProxyResolver(env, cproto, chost);
|
||||
else if (use_gconf)
|
||||
proxy = getProxyByGConf(env, cproto, chost);
|
||||
|
||||
proxyArray = getProxyByGConf(env, cproto, chost);
|
||||
if (isHostCopy == JNI_TRUE)
|
||||
(*env)->ReleaseStringUTFChars(env, host, chost);
|
||||
}
|
||||
if (isProtoCopy == JNI_TRUE)
|
||||
(*env)->ReleaseStringUTFChars(env, proto, cproto);
|
||||
}
|
||||
return proxy;
|
||||
return proxyArray;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,26 +24,24 @@
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <Winhttp.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
|
||||
#include "proxy_util.h"
|
||||
|
||||
#include "sun_net_spi_DefaultProxySelector.h"
|
||||
|
||||
/**
|
||||
/*
|
||||
* These functions are used by the sun.net.spi.DefaultProxySelector class
|
||||
* to access some platform specific settings.
|
||||
* This is the Windows code using the registry settings.
|
||||
* On Windows use WinHTTP functions to get the system settings.
|
||||
*/
|
||||
|
||||
static jclass proxy_class;
|
||||
static jclass isaddr_class;
|
||||
static jclass ptype_class;
|
||||
static jmethodID isaddr_createUnresolvedID;
|
||||
static jmethodID proxy_ctrID;
|
||||
static jfieldID pr_no_proxyID;
|
||||
static jfieldID ptype_httpID;
|
||||
static jfieldID ptype_socksID;
|
||||
/* Keep one static session for all requests. */
|
||||
static HINTERNET session = NULL;
|
||||
|
||||
/*
|
||||
* Class: sun_net_spi_DefaultProxySelector
|
||||
@ -52,233 +50,327 @@ static jfieldID ptype_socksID;
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
|
||||
HKEY hKey;
|
||||
LONG ret;
|
||||
jclass cls;
|
||||
|
||||
/**
|
||||
* Get all the method & field IDs for later use.
|
||||
*/
|
||||
cls = (*env)->FindClass(env,"java/net/Proxy");
|
||||
CHECK_NULL_RETURN(cls, JNI_FALSE);
|
||||
proxy_class = (*env)->NewGlobalRef(env, cls);
|
||||
CHECK_NULL_RETURN(proxy_class, JNI_FALSE);
|
||||
cls = (*env)->FindClass(env,"java/net/Proxy$Type");
|
||||
CHECK_NULL_RETURN(cls, JNI_FALSE);
|
||||
ptype_class = (*env)->NewGlobalRef(env, cls);
|
||||
CHECK_NULL_RETURN(ptype_class, JNI_FALSE);
|
||||
cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
|
||||
CHECK_NULL_RETURN(cls, JNI_FALSE);
|
||||
isaddr_class = (*env)->NewGlobalRef(env, cls);
|
||||
CHECK_NULL_RETURN(isaddr_class, JNI_FALSE);
|
||||
proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>",
|
||||
"(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
|
||||
CHECK_NULL_RETURN(proxy_ctrID, JNI_FALSE);
|
||||
pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY", "Ljava/net/Proxy;");
|
||||
CHECK_NULL_RETURN(pr_no_proxyID, JNI_FALSE);
|
||||
ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP", "Ljava/net/Proxy$Type;");
|
||||
CHECK_NULL_RETURN(ptype_httpID, JNI_FALSE);
|
||||
ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS", "Ljava/net/Proxy$Type;");
|
||||
CHECK_NULL_RETURN(ptype_socksID, JNI_FALSE);
|
||||
isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class, "createUnresolved",
|
||||
"(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
|
||||
CHECK_NULL_RETURN(isaddr_createUnresolvedID, JNI_FALSE);
|
||||
|
||||
/**
|
||||
* Let's see if we can find the proper Registry entry.
|
||||
*/
|
||||
ret = RegOpenKeyEx(HKEY_CURRENT_USER,
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
|
||||
0, KEY_READ, (PHKEY)&hKey);
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
RegCloseKey(hKey);
|
||||
/**
|
||||
* It worked, we can probably rely on it then.
|
||||
/*
|
||||
* Get one WinHTTP session handle to initialize the WinHTTP internal data
|
||||
* structures. Keep and use only this one for the whole life time.
|
||||
*/
|
||||
return JNI_TRUE;
|
||||
}
|
||||
session = WinHttpOpen(L"Only used internal", /* we need no real agent string here */
|
||||
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
||||
WINHTTP_NO_PROXY_NAME,
|
||||
WINHTTP_NO_PROXY_BYPASS,
|
||||
0);
|
||||
if (session == NULL) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
return JNI_FALSE;
|
||||
if (!initJavaClass(env)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#define MAX_STR_LEN 1024
|
||||
|
||||
/* A linked list element for a proxy */
|
||||
typedef struct list_item {
|
||||
wchar_t *host;
|
||||
int port;
|
||||
struct list_item *next;
|
||||
} list_item;
|
||||
|
||||
/* Free the linked list */
|
||||
static void freeList(list_item *head) {
|
||||
list_item *next = NULL;
|
||||
list_item *current = head;
|
||||
while (current != NULL) {
|
||||
next = current->next;
|
||||
free(current->host);
|
||||
free(current);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Creates a linked list of list_item elements that has to be freed later on.
|
||||
* Returns the size of the array as int.
|
||||
*/
|
||||
static int createProxyList(LPWSTR win_proxy, const WCHAR *pproto, list_item **head) {
|
||||
static const wchar_t separators[] = L"\t\r\n ;";
|
||||
list_item *current = NULL;
|
||||
int nr_elems = 0;
|
||||
wchar_t *context = NULL;
|
||||
wchar_t *current_proxy = NULL;
|
||||
BOOL error = FALSE;
|
||||
|
||||
/*
|
||||
* The proxy server list contains one or more of the following strings
|
||||
* separated by semicolons or whitespace:
|
||||
* ([<scheme>=][<scheme>"://"]<server>[":"<port>])
|
||||
*/
|
||||
current_proxy = wcstok_s(win_proxy, separators, &context);
|
||||
while (current_proxy != NULL) {
|
||||
LPWSTR pport;
|
||||
LPWSTR phost;
|
||||
int portVal = 0;
|
||||
wchar_t *next_proxy = NULL;
|
||||
list_item *proxy = NULL;
|
||||
wchar_t* pos = NULL;
|
||||
|
||||
/* Filter based on the scheme, if there is one */
|
||||
pos = wcschr(current_proxy, L'=');
|
||||
if (pos) {
|
||||
*pos = L'\0';
|
||||
if (wcscmp(current_proxy, pproto) != 0) {
|
||||
current_proxy = wcstok_s(NULL, separators, &context);
|
||||
continue;
|
||||
}
|
||||
current_proxy = pos + 1;
|
||||
}
|
||||
|
||||
/* Let's check for a scheme and ignore it. */
|
||||
if ((phost = wcsstr(current_proxy, L"://")) != NULL) {
|
||||
phost += 3;
|
||||
} else {
|
||||
phost = current_proxy;
|
||||
}
|
||||
|
||||
/* Get the port */
|
||||
pport = wcschr(phost, L':');
|
||||
if (pport != NULL) {
|
||||
*pport = 0;
|
||||
pport++;
|
||||
swscanf(pport, L"%d", &portVal);
|
||||
}
|
||||
|
||||
proxy = (list_item *)malloc(sizeof(list_item));
|
||||
if (proxy != NULL) {
|
||||
proxy->next = NULL;
|
||||
proxy->port = portVal;
|
||||
proxy->host = _wcsdup(phost);
|
||||
|
||||
if (proxy->host != NULL) {
|
||||
if (*head == NULL) {
|
||||
*head = proxy; /* first elem */
|
||||
}
|
||||
if (current != NULL) {
|
||||
current->next = proxy;
|
||||
}
|
||||
current = proxy;
|
||||
nr_elems++;
|
||||
} else {
|
||||
free(proxy); /* cleanup */
|
||||
}
|
||||
}
|
||||
/* goto next proxy if available... */
|
||||
current_proxy = wcstok_s(NULL, separators, &context);
|
||||
}
|
||||
return nr_elems;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_net_spi_DefaultProxySelector
|
||||
* Method: getSystemProxy
|
||||
* Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;
|
||||
* Method: getSystemProxies
|
||||
* Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
|
||||
jobject this,
|
||||
jstring proto,
|
||||
jstring host)
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
|
||||
jobject this,
|
||||
jstring proto,
|
||||
jstring host)
|
||||
{
|
||||
jobject isa = NULL;
|
||||
jobject proxy = NULL;
|
||||
jobject type_proxy = NULL;
|
||||
jobject no_proxy = NULL;
|
||||
jboolean isCopy;
|
||||
HKEY hKey;
|
||||
LONG ret;
|
||||
const char* cproto;
|
||||
const char* urlhost;
|
||||
char pproto[MAX_STR_LEN];
|
||||
char regserver[MAX_STR_LEN];
|
||||
char override[MAX_STR_LEN];
|
||||
char *s, *s2;
|
||||
char *ctx = NULL;
|
||||
int pport = 0;
|
||||
int defport = 0;
|
||||
char *phost;
|
||||
jobjectArray proxy_array = NULL;
|
||||
jobject type_proxy = NULL;
|
||||
LPCWSTR lpProto;
|
||||
LPCWSTR lpHost;
|
||||
list_item *head = NULL;
|
||||
|
||||
/**
|
||||
* Let's open the Registry entry. We'll check a few values in it:
|
||||
*
|
||||
* - ProxyEnable: 0 means no proxy, 1 means use the proxy
|
||||
* - ProxyServer: a string that can take 2 forms:
|
||||
* "server[:port]"
|
||||
* or
|
||||
* "protocol1=server[:port][;protocol2=server[:port]]..."
|
||||
* - ProxyOverride: a string containing a list of prefixes for hostnames.
|
||||
* e.g.: hoth;localhost;<local>
|
||||
*/
|
||||
ret = RegOpenKeyEx(HKEY_CURRENT_USER,
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
|
||||
0, KEY_READ, (PHKEY)&hKey);
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
DWORD dwLen;
|
||||
DWORD dwProxyEnabled;
|
||||
ULONG ulType;
|
||||
dwLen = sizeof(dwProxyEnabled);
|
||||
BOOL use_auto_proxy = FALSE;
|
||||
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_proxy_config;
|
||||
WINHTTP_AUTOPROXY_OPTIONS auto_proxy_options;
|
||||
WINHTTP_PROXY_INFO proxy_info;
|
||||
LPWSTR win_proxy = NULL;
|
||||
LPWSTR win_bypass_proxy = NULL;
|
||||
|
||||
/**
|
||||
* Let's see if the proxy settings are to be used.
|
||||
*/
|
||||
ret = RegQueryValueEx(hKey, "ProxyEnable", NULL, &ulType,
|
||||
(LPBYTE)&dwProxyEnabled, &dwLen);
|
||||
if ((ret == ERROR_SUCCESS) && (dwProxyEnabled > 0)) {
|
||||
/*
|
||||
* Yes, ProxyEnable == 1
|
||||
*/
|
||||
dwLen = sizeof(override);
|
||||
override[0] = 0;
|
||||
ret = RegQueryValueEx(hKey, "ProxyOverride", NULL, &ulType,
|
||||
(LPBYTE)&override, &dwLen);
|
||||
dwLen = sizeof(regserver);
|
||||
regserver[0] = 0;
|
||||
ret = RegQueryValueEx(hKey, "ProxyServer", NULL, &ulType,
|
||||
(LPBYTE)®server, &dwLen);
|
||||
RegCloseKey(hKey);
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
if (strlen(override) > 0) {
|
||||
/**
|
||||
* we did get ProxyServer and may have an override.
|
||||
* So let's check the override list first, by walking down the list
|
||||
* The semicolons (;) separated entries have to be matched with the
|
||||
* the beginning of the hostname.
|
||||
*/
|
||||
s = strtok_s(override, "; ", &ctx);
|
||||
urlhost = (*env)->GetStringUTFChars(env, host, &isCopy);
|
||||
if (urlhost == NULL) {
|
||||
if (!(*env)->ExceptionCheck(env))
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
return NULL;
|
||||
}
|
||||
while (s != NULL) {
|
||||
if (strncmp(s, urlhost, strlen(s)) == 0) {
|
||||
/**
|
||||
* the URL host name matches with one of the prefixes,
|
||||
* therefore we have to use a direct connection.
|
||||
*/
|
||||
if (isCopy == JNI_TRUE)
|
||||
(*env)->ReleaseStringUTFChars(env, host, urlhost);
|
||||
goto noproxy;
|
||||
}
|
||||
s = strtok_s(NULL, "; ", &ctx);
|
||||
}
|
||||
if (isCopy == JNI_TRUE)
|
||||
(*env)->ReleaseStringUTFChars(env, host, urlhost);
|
||||
}
|
||||
memset(&ie_proxy_config, 0, sizeof(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG));
|
||||
memset(&auto_proxy_options, 0, sizeof(WINHTTP_AUTOPROXY_OPTIONS));
|
||||
memset(&proxy_info, 0, sizeof(WINHTTP_PROXY_INFO));
|
||||
|
||||
cproto = (*env)->GetStringUTFChars(env, proto, &isCopy);
|
||||
if (cproto == NULL) {
|
||||
if (!(*env)->ExceptionCheck(env))
|
||||
lpHost = (*env)->GetStringChars(env, host, NULL);
|
||||
if (lpHost == NULL) {
|
||||
if (!(*env)->ExceptionCheck(env))
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set default port value & proxy type from protocol.
|
||||
*/
|
||||
if ((strcmp(cproto, "http") == 0) ||
|
||||
(strcmp(cproto, "ftp") == 0) ||
|
||||
(strcmp(cproto, "gopher") == 0))
|
||||
defport = 80;
|
||||
if (strcmp(cproto, "https") == 0)
|
||||
defport = 443;
|
||||
if (strcmp(cproto, "socks") == 0) {
|
||||
defport = 1080;
|
||||
type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);
|
||||
} else {
|
||||
type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
|
||||
}
|
||||
|
||||
sprintf(pproto,"%s=", cproto);
|
||||
if (isCopy == JNI_TRUE)
|
||||
(*env)->ReleaseStringUTFChars(env, proto, cproto);
|
||||
/**
|
||||
* Let's check the protocol specific form first.
|
||||
*/
|
||||
if ((s = strstr(regserver, pproto)) != NULL) {
|
||||
s += strlen(pproto);
|
||||
} else {
|
||||
/**
|
||||
* If we couldn't find *this* protocol but the string is in the
|
||||
* protocol specific format, then don't use proxy
|
||||
*/
|
||||
if (strchr(regserver, '=') != NULL)
|
||||
goto noproxy;
|
||||
s = regserver;
|
||||
}
|
||||
s2 = strchr(s, ';');
|
||||
if (s2 != NULL)
|
||||
*s2 = 0;
|
||||
|
||||
/**
|
||||
* Is there a port specified?
|
||||
*/
|
||||
s2 = strchr(s, ':');
|
||||
if (s2 != NULL) {
|
||||
*s2 = 0;
|
||||
s2++;
|
||||
sscanf(s2, "%d", &pport);
|
||||
}
|
||||
phost = s;
|
||||
|
||||
if (phost != NULL) {
|
||||
/**
|
||||
* Let's create the appropriate Proxy object then.
|
||||
*/
|
||||
jstring jhost;
|
||||
if (pport == 0)
|
||||
pport = defport;
|
||||
jhost = (*env)->NewStringUTF(env, phost);
|
||||
CHECK_NULL_RETURN(jhost, NULL);
|
||||
isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, pport);
|
||||
CHECK_NULL_RETURN(isa, NULL);
|
||||
proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* ProxyEnable == 0 or Query failed */
|
||||
/* close the handle to the registry key */
|
||||
RegCloseKey(hKey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lpProto = (*env)->GetStringChars(env, proto, NULL);
|
||||
if (lpProto == NULL) {
|
||||
(*env)->ReleaseStringChars(env, host, lpHost);
|
||||
if (!(*env)->ExceptionCheck(env))
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (WinHttpGetIEProxyConfigForCurrentUser(&ie_proxy_config) == FALSE) {
|
||||
/* cleanup and exit */
|
||||
(*env)->ReleaseStringChars(env, host, lpHost);
|
||||
(*env)->ReleaseStringChars(env, proto, lpProto);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ie_proxy_config.fAutoDetect) {
|
||||
/* Windows uses WPAD */
|
||||
auto_proxy_options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP |
|
||||
WINHTTP_AUTO_DETECT_TYPE_DNS_A;
|
||||
auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
|
||||
auto_proxy_options.fAutoLogonIfChallenged = TRUE;
|
||||
use_auto_proxy = TRUE;
|
||||
} else if (ie_proxy_config.lpszAutoConfigUrl != NULL) {
|
||||
/* Windows uses PAC file */
|
||||
auto_proxy_options.lpszAutoConfigUrl = ie_proxy_config.lpszAutoConfigUrl;
|
||||
auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
|
||||
use_auto_proxy = TRUE;
|
||||
} else if (ie_proxy_config.lpszProxy != NULL) {
|
||||
/* Windows uses manually entered proxy. */
|
||||
use_auto_proxy = FALSE;
|
||||
win_bypass_proxy = ie_proxy_config.lpszProxyBypass;
|
||||
win_proxy = ie_proxy_config.lpszProxy;
|
||||
}
|
||||
|
||||
if (use_auto_proxy) {
|
||||
WCHAR url[MAX_STR_LEN];
|
||||
/* Create url for WinHttpGetProxyForUrl */
|
||||
_snwprintf(url, sizeof(url) - 1, L"%s://%s", lpProto, lpHost);
|
||||
/* Get proxy for URL from Windows */
|
||||
use_auto_proxy = WinHttpGetProxyForUrl(session, &url[0], &auto_proxy_options, &proxy_info);
|
||||
if (use_auto_proxy) {
|
||||
win_proxy = proxy_info.lpszProxy;
|
||||
win_bypass_proxy = proxy_info.lpszProxyBypass;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the bypass entry. */
|
||||
if (NULL != win_bypass_proxy) {
|
||||
/*
|
||||
* From MSDN:
|
||||
* The proxy bypass list contains one or more server names separated by
|
||||
* semicolons or whitespace. The proxy bypass list can also contain the
|
||||
* string "<local>" to indicate that all local intranet sites are
|
||||
* bypassed. Local intranet sites are considered to be all servers that
|
||||
* do not contain a period in their name.
|
||||
*/
|
||||
wchar_t *context = NULL;
|
||||
LPWSTR s = wcstok_s(win_bypass_proxy, L"; ", &context);
|
||||
|
||||
while (s != NULL) {
|
||||
size_t maxlen = wcslen(s);
|
||||
if (wcsncmp(s, lpHost, maxlen) == 0) {
|
||||
/*
|
||||
* The URL host name matches with one of the prefixes, use a
|
||||
* direct connection.
|
||||
*/
|
||||
goto noproxy;
|
||||
}
|
||||
if (wcsncmp(s, L"<local>", maxlen) == 0) {
|
||||
/*
|
||||
* All local intranet sites are bypassed - Microsoft consider all
|
||||
* servers that do not contain a period in their name to be local.
|
||||
*/
|
||||
if (wcschr(lpHost, '.') == NULL) {
|
||||
goto noproxy;
|
||||
}
|
||||
}
|
||||
s = wcstok_s(NULL, L"; ", &context);
|
||||
}
|
||||
}
|
||||
|
||||
if (win_proxy != NULL) {
|
||||
wchar_t *context = NULL;
|
||||
int defport = 0;
|
||||
int nr_elems = 0;
|
||||
|
||||
/* Set the default port value & proxy type from protocol. */
|
||||
if ((wcscmp(lpProto, L"http") == 0) ||
|
||||
(wcscmp(lpProto, L"ftp") == 0) ||
|
||||
(wcscmp(lpProto, L"gopher") == 0))
|
||||
defport = 80;
|
||||
if (wcscmp(lpProto, L"https") == 0)
|
||||
defport = 443;
|
||||
if (wcscmp(lpProto, L"socks") == 0) {
|
||||
defport = 1080;
|
||||
type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);
|
||||
} else {
|
||||
type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
|
||||
}
|
||||
if (type_proxy == NULL || (*env)->ExceptionCheck(env)) {
|
||||
goto noproxy;
|
||||
}
|
||||
|
||||
nr_elems = createProxyList(win_proxy, lpProto, &head);
|
||||
if (nr_elems != 0 && head != NULL) {
|
||||
int index = 0;
|
||||
proxy_array = (*env)->NewObjectArray(env, nr_elems, proxy_class, NULL);
|
||||
if (proxy_array == NULL || (*env)->ExceptionCheck(env)) {
|
||||
goto noproxy;
|
||||
}
|
||||
while (head != NULL && index < nr_elems) {
|
||||
jstring jhost;
|
||||
jobject isa;
|
||||
jobject proxy;
|
||||
|
||||
if (head->host != NULL && proxy_array != NULL) {
|
||||
/* Let's create the appropriate Proxy object then. */
|
||||
if (head->port == 0) {
|
||||
head->port = defport;
|
||||
}
|
||||
jhost = (*env)->NewString(env, head->host, (jsize)wcslen(head->host));
|
||||
if (jhost == NULL || (*env)->ExceptionCheck(env)) {
|
||||
proxy_array = NULL;
|
||||
}
|
||||
isa = (*env)->CallStaticObjectMethod(env, isaddr_class,
|
||||
isaddr_createUnresolvedID, jhost,
|
||||
head->port);
|
||||
if (isa == NULL || (*env)->ExceptionCheck(env)) {
|
||||
proxy_array = NULL;
|
||||
}
|
||||
proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
|
||||
if (proxy == NULL || (*env)->ExceptionCheck(env)) {
|
||||
proxy_array = NULL;
|
||||
}
|
||||
(*env)->SetObjectArrayElement(env, proxy_array, index, proxy);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
proxy_array = NULL;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
noproxy:
|
||||
no_proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID);
|
||||
return no_proxy;
|
||||
if (head != NULL) {
|
||||
freeList(head);
|
||||
}
|
||||
if (proxy_info.lpszProxy != NULL)
|
||||
GlobalFree(proxy_info.lpszProxy);
|
||||
if (proxy_info.lpszProxyBypass != NULL)
|
||||
GlobalFree(proxy_info.lpszProxyBypass);
|
||||
if (ie_proxy_config.lpszAutoConfigUrl != NULL)
|
||||
GlobalFree(ie_proxy_config.lpszAutoConfigUrl);
|
||||
if (ie_proxy_config.lpszProxy != NULL)
|
||||
GlobalFree(ie_proxy_config.lpszProxy);
|
||||
if (ie_proxy_config.lpszProxyBypass != NULL)
|
||||
GlobalFree(ie_proxy_config.lpszProxyBypass);
|
||||
if (lpHost != NULL)
|
||||
(*env)->ReleaseStringChars(env, host, lpHost);
|
||||
if (lpProto != NULL)
|
||||
(*env)->ReleaseStringChars(env, proto, lpProto);
|
||||
|
||||
return proxy_array;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,9 +22,13 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a manual test to determine the proxies set on the system for various
|
||||
* protocols. See bug 6912868.
|
||||
* @test
|
||||
* @bug 6912868 8170868
|
||||
* @summary Basic test to provide some coverage of system proxy code. Will
|
||||
* always pass. Should be run manually for specific systems to inspect output.
|
||||
* @run main/othervm -Djava.net.useSystemProxies=true SystemProxies
|
||||
*/
|
||||
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.URI;
|
||||
|
Loading…
Reference in New Issue
Block a user