Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/native/sun/net/spi/DefaultProxySelector.c
32288 views
/*1* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include <windows.h>26#include "jni.h"27#include "jni_util.h"28#include "jvm.h"29#include "jlong.h"30#include "sun_net_spi_DefaultProxySelector.h"3132/**33* These functions are used by the sun.net.spi.DefaultProxySelector class34* to access some platform specific settings.35* This is the Windows code using the registry settings.36*/3738static jclass proxy_class;39static jclass isaddr_class;40static jclass ptype_class;41static jmethodID isaddr_createUnresolvedID;42static jmethodID proxy_ctrID;43static jfieldID pr_no_proxyID;44static jfieldID ptype_httpID;45static jfieldID ptype_socksID;4647#define CHECK_NULL(X) { if ((X) == NULL) fprintf (stderr,"JNI errror at line %d\n", __LINE__); }484950/*51* Class: sun_net_spi_DefaultProxySelector52* Method: init53* Signature: ()Z54*/55JNIEXPORT jboolean JNICALL56Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {57HKEY hKey;58LONG ret;59jclass cls;6061/**62* Get all the method & field IDs for later use.63*/64CHECK_NULL(cls = (*env)->FindClass(env,"java/net/Proxy"));65proxy_class = (*env)->NewGlobalRef(env, cls);66CHECK_NULL(cls = (*env)->FindClass(env,"java/net/Proxy$Type"));67ptype_class = (*env)->NewGlobalRef(env, cls);68CHECK_NULL(cls = (*env)->FindClass(env, "java/net/InetSocketAddress"));69isaddr_class = (*env)->NewGlobalRef(env, cls);70proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>", "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");71pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY", "Ljava/net/Proxy;");72ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP", "Ljava/net/Proxy$Type;");73ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS", "Ljava/net/Proxy$Type;");74isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class, "createUnresolved", "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");7576/**77* Let's see if we can find the proper Registry entry.78*/79ret = RegOpenKeyEx(HKEY_CURRENT_USER,80"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",810, KEY_READ, (PHKEY)&hKey);82if (ret == ERROR_SUCCESS) {83RegCloseKey(hKey);84/**85* It worked, we can probably rely on it then.86*/87return JNI_TRUE;88}8990return JNI_FALSE;91}9293#define MAX_STR_LEN 10249495/*96* Class: sun_net_spi_DefaultProxySelector97* Method: getSystemProxy98* Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;99*/100JNIEXPORT jobject JNICALL101Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,102jobject this,103jstring proto,104jstring host)105{106jobject isa = NULL;107jobject proxy = NULL;108jobject type_proxy = NULL;109jobject no_proxy = NULL;110jboolean isCopy;111HKEY hKey;112LONG ret;113const char* cproto;114const char* urlhost;115char pproto[MAX_STR_LEN];116char regserver[MAX_STR_LEN];117char override[MAX_STR_LEN];118char *s, *s2;119char *ctx = NULL;120int pport = 0;121int defport = 0;122char *phost;123124/**125* Let's open the Registry entry. We'll check a few values in it:126*127* - ProxyEnable: 0 means no proxy, 1 means use the proxy128* - ProxyServer: a string that can take 2 forms:129* "server[:port]"130* or131* "protocol1=server[:port][;protocol2=server[:port]]..."132* - ProxyOverride: a string containing a list of prefixes for hostnames.133* e.g.: hoth;localhost;<local>134*/135ret = RegOpenKeyEx(HKEY_CURRENT_USER,136"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",1370, KEY_READ, (PHKEY)&hKey);138if (ret == ERROR_SUCCESS) {139DWORD dwLen;140DWORD dwProxyEnabled;141ULONG ulType;142dwLen = sizeof(dwProxyEnabled);143144/**145* Let's see if the proxy settings are to be used.146*/147ret = RegQueryValueEx(hKey, "ProxyEnable", NULL, &ulType,148(LPBYTE)&dwProxyEnabled, &dwLen);149if ((ret == ERROR_SUCCESS) && (dwProxyEnabled > 0)) {150/*151* Yes, ProxyEnable == 1152*/153dwLen = sizeof(override);154override[0] = 0;155ret = RegQueryValueEx(hKey, "ProxyOverride", NULL, &ulType,156(LPBYTE)&override, &dwLen);157dwLen = sizeof(regserver);158regserver[0] = 0;159ret = RegQueryValueEx(hKey, "ProxyServer", NULL, &ulType,160(LPBYTE)®server, &dwLen);161RegCloseKey(hKey);162if (ret == ERROR_SUCCESS) {163if (strlen(override) > 0) {164/**165* we did get ProxyServer and may have an override.166* So let's check the override list first, by walking down the list167* The semicolons (;) separated entries have to be matched with the168* the beginning of the hostname.169*/170s = strtok_s(override, "; ", &ctx);171urlhost = (*env)->GetStringUTFChars(env, host, &isCopy);172if (urlhost == NULL) {173if (!(*env)->ExceptionCheck(env))174JNU_ThrowOutOfMemoryError(env, NULL);175return NULL;176}177while (s != NULL) {178if (strncmp(s, urlhost, strlen(s)) == 0) {179/**180* the URL host name matches with one of the prefixes,181* therefore we have to use a direct connection.182*/183if (isCopy == JNI_TRUE)184(*env)->ReleaseStringUTFChars(env, host, urlhost);185goto noproxy;186}187s = strtok_s(NULL, "; ", &ctx);188}189if (isCopy == JNI_TRUE)190(*env)->ReleaseStringUTFChars(env, host, urlhost);191}192193cproto = (*env)->GetStringUTFChars(env, proto, &isCopy);194if (cproto == NULL) {195if (!(*env)->ExceptionCheck(env))196JNU_ThrowOutOfMemoryError(env, NULL);197return NULL;198}199200/*201* Set default port value & proxy type from protocol.202*/203if ((strcmp(cproto, "http") == 0) ||204(strcmp(cproto, "ftp") == 0) ||205(strcmp(cproto, "gopher") == 0))206defport = 80;207if (strcmp(cproto, "https") == 0)208defport = 443;209if (strcmp(cproto, "socks") == 0) {210defport = 1080;211type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);212} else {213type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);214}215216sprintf(pproto,"%s=", cproto);217if (isCopy == JNI_TRUE)218(*env)->ReleaseStringUTFChars(env, proto, cproto);219/**220* Let's check the protocol specific form first.221*/222if ((s = strstr(regserver, pproto)) != NULL) {223s += strlen(pproto);224} else {225/**226* If we couldn't find *this* protocol but the string is in the227* protocol specific format, then don't use proxy228*/229if (strchr(regserver, '=') != NULL)230goto noproxy;231s = regserver;232}233s2 = strchr(s, ';');234if (s2 != NULL)235*s2 = 0;236237/**238* Is there a port specified?239*/240s2 = strchr(s, ':');241if (s2 != NULL) {242*s2 = 0;243s2++;244sscanf(s2, "%d", &pport);245}246phost = s;247248if (phost != NULL) {249/**250* Let's create the appropriate Proxy object then.251*/252jstring jhost;253if (pport == 0)254pport = defport;255jhost = (*env)->NewStringUTF(env, phost);256CHECK_NULL_RETURN(jhost, NULL);257isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, pport);258CHECK_NULL_RETURN(isa, NULL);259proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);260return proxy;261}262}263} else {264/* ProxyEnable == 0 or Query failed */265/* close the handle to the registry key */266RegCloseKey(hKey);267}268}269270noproxy:271no_proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID);272return no_proxy;273}274275276