1 /*
2 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include <windows.h>
27 #include "jni.h"
28 #include "jni_util.h"
29 #include "jvm.h"
30 #include "jlong.h"
31 #include "sun_net_spi_DefaultProxySelector.h"
32
33 /**
34 * These functions are used by the sun.net.spi.DefaultProxySelector class
35 * to access some platform specific settings.
36 * This is the Windows code using the registry settings.
37 */
38
39 static jclass proxy_class;
40 static jclass isaddr_class;
41 static jclass ptype_class;
42 static jmethodID isaddr_createUnresolvedID;
43 static jmethodID proxy_ctrID;
44 static jfieldID pr_no_proxyID;
45 static jfieldID ptype_httpID;
46 static jfieldID ptype_socksID;
47
48 /*
49 * Class: sun_net_spi_DefaultProxySelector
50 * Method: init
51 * Signature: ()Z
52 */
53 JNIEXPORT jboolean JNICALL
54 Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
55 HKEY hKey;
56 LONG ret;
57 jclass cls;
58
59 /**
60 * Get all the method & field IDs for later use.
61 */
62 cls = (*env)->FindClass(env,"java/net/Proxy");
63 CHECK_NULL_RETURN(cls, JNI_FALSE);
64 proxy_class = (*env)->NewGlobalRef(env, cls);
65 CHECK_NULL_RETURN(proxy_class, JNI_FALSE);
66 cls = (*env)->FindClass(env,"java/net/Proxy$Type");
67 CHECK_NULL_RETURN(cls, JNI_FALSE);
68 ptype_class = (*env)->NewGlobalRef(env, cls);
69 CHECK_NULL_RETURN(ptype_class, JNI_FALSE);
70 cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
71 CHECK_NULL_RETURN(cls, JNI_FALSE);
72 isaddr_class = (*env)->NewGlobalRef(env, cls);
73 CHECK_NULL_RETURN(isaddr_class, JNI_FALSE);
74 proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>",
75 "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
76 CHECK_NULL_RETURN(proxy_ctrID, JNI_FALSE);
77 pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY", "Ljava/net/Proxy;");
78 CHECK_NULL_RETURN(pr_no_proxyID, JNI_FALSE);
79 ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP", "Ljava/net/Proxy$Type;");
80 CHECK_NULL_RETURN(ptype_httpID, JNI_FALSE);
81 ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS", "Ljava/net/Proxy$Type;");
82 CHECK_NULL_RETURN(ptype_socksID, JNI_FALSE);
83 isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class, "createUnresolved",
84 "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
85 CHECK_NULL_RETURN(isaddr_createUnresolvedID, JNI_FALSE);
86
87 /**
88 * Let's see if we can find the proper Registry entry.
89 */
90 ret = RegOpenKeyEx(HKEY_CURRENT_USER,
91 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
92 0, KEY_READ, (PHKEY)&hKey);
93 if (ret == ERROR_SUCCESS) {
94 RegCloseKey(hKey);
95 /**
96 * It worked, we can probably rely on it then.
97 */
98 return JNI_TRUE;
99 }
100
101 return JNI_FALSE;
102 }
103
104 #define MAX_STR_LEN 1024
105
106 /*
107 * Class: sun_net_spi_DefaultProxySelector
108 * Method: getSystemProxy
109 * Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;
110 */
111 JNIEXPORT jobject JNICALL
112 Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
113 jobject this,
114 jstring proto,
115 jstring host)
116 {
117 jobject isa = NULL;
118 jobject proxy = NULL;
119 jobject type_proxy = NULL;
120 jobject no_proxy = NULL;
121 jboolean isCopy;
122 HKEY hKey;
123 LONG ret;
124 const char* cproto;
125 const char* urlhost;
126 char pproto[MAX_STR_LEN];
127 char regserver[MAX_STR_LEN];
128 char override[MAX_STR_LEN];
129 char *s, *s2;
130 char *ctx = NULL;
131 int pport = 0;
132 int defport = 0;
133 char *phost;
134
135 /**
136 * Let's open the Registry entry. We'll check a few values in it:
137 *
138 * - ProxyEnable: 0 means no proxy, 1 means use the proxy
139 * - ProxyServer: a string that can take 2 forms:
140 * "server[:port]"
141 * or
142 * "protocol1=server[:port][;protocol2=server[:port]]..."
143 * - ProxyOverride: a string containing a list of prefixes for hostnames.
144 * e.g.: hoth;localhost;<local>
145 */
146 ret = RegOpenKeyEx(HKEY_CURRENT_USER,
147 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
148 0, KEY_READ, (PHKEY)&hKey);
149 if (ret == ERROR_SUCCESS) {
150 DWORD dwLen;
151 DWORD dwProxyEnabled;
152 ULONG ulType;
153 dwLen = sizeof(dwProxyEnabled);
154
155 /**
156 * Let's see if the proxy settings are to be used.
157 */
158 ret = RegQueryValueEx(hKey, "ProxyEnable", NULL, &ulType,
159 (LPBYTE)&dwProxyEnabled, &dwLen);
160 if ((ret == ERROR_SUCCESS) && (dwProxyEnabled > 0)) {
161 /*
162 * Yes, ProxyEnable == 1
163 */
164 dwLen = sizeof(override);
165 override[0] = 0;
166 ret = RegQueryValueEx(hKey, "ProxyOverride", NULL, &ulType,
167 (LPBYTE)&override, &dwLen);
168 dwLen = sizeof(regserver);
169 regserver[0] = 0;
170 ret = RegQueryValueEx(hKey, "ProxyServer", NULL, &ulType,
171 (LPBYTE)®server, &dwLen);
172 RegCloseKey(hKey);
173 if (ret == ERROR_SUCCESS) {
174 if (strlen(override) > 0) {
175 /**
176 * we did get ProxyServer and may have an override.
177 * So let's check the override list first, by walking down the list
178 * The semicolons (;) separated entries have to be matched with the
179 * the beginning of the hostname.
180 */
181 s = strtok_s(override, "; ", &ctx);
182 urlhost = (*env)->GetStringUTFChars(env, host, &isCopy);
183 if (urlhost == NULL) {
184 if (!(*env)->ExceptionCheck(env))
185 JNU_ThrowOutOfMemoryError(env, NULL);
186 return NULL;
187 }
188 while (s != NULL) {
189 if (strncmp(s, urlhost, strlen(s)) == 0) {
190 /**
191 * the URL host name matches with one of the prefixes,
192 * therefore we have to use a direct connection.
193 */
194 if (isCopy == JNI_TRUE)
195 (*env)->ReleaseStringUTFChars(env, host, urlhost);
196 goto noproxy;
197 }
198 s = strtok_s(NULL, "; ", &ctx);
199 }
200 if (isCopy == JNI_TRUE)
201 (*env)->ReleaseStringUTFChars(env, host, urlhost);
202 }
203
204 cproto = (*env)->GetStringUTFChars(env, proto, &isCopy);
205 if (cproto == NULL) {
206 if (!(*env)->ExceptionCheck(env))
207 JNU_ThrowOutOfMemoryError(env, NULL);
208 return NULL;
209 }
210
211 /*
212 * Set default port value & proxy type from protocol.
213 */
214 if ((strcmp(cproto, "http") == 0) ||
215 (strcmp(cproto, "ftp") == 0) ||
216 (strcmp(cproto, "gopher") == 0))
217 defport = 80;
218 if (strcmp(cproto, "https") == 0)
219 defport = 443;
220 if (strcmp(cproto, "socks") == 0) {
221 defport = 1080;
222 type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);
223 } else {
224 type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
225 }
226
227 sprintf(pproto,"%s=", cproto);
228 if (isCopy == JNI_TRUE)
229 (*env)->ReleaseStringUTFChars(env, proto, cproto);
230 /**
231 * Let's check the protocol specific form first.
232 */
233 if ((s = strstr(regserver, pproto)) != NULL) {
234 s += strlen(pproto);
235 } else {
236 /**
237 * If we couldn't find *this* protocol but the string is in the
238 * protocol specific format, then don't use proxy
239 */
240 if (strchr(regserver, '=') != NULL)
241 goto noproxy;
242 s = regserver;
243 }
244 s2 = strchr(s, ';');
245 if (s2 != NULL)
246 *s2 = 0;
247
248 /**
249 * Is there a port specified?
250 */
251 s2 = strchr(s, ':');
252 if (s2 != NULL) {
253 *s2 = 0;
254 s2++;
255 sscanf(s2, "%d", &pport);
256 }
257 phost = s;
258
259 if (phost != NULL) {
260 /**
261 * Let's create the appropriate Proxy object then.
262 */
263 jstring jhost;
264 if (pport == 0)
265 pport = defport;
266 jhost = (*env)->NewStringUTF(env, phost);
267 CHECK_NULL_RETURN(jhost, NULL);
268 isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, pport);
269 CHECK_NULL_RETURN(isa, NULL);
270 proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
271 return proxy;
272 }
273 }
274 } else {
275 /* ProxyEnable == 0 or Query failed */
276 /* close the handle to the registry key */
277 RegCloseKey(hKey);
278 }
279 }
280
281 noproxy:
282 no_proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID);
283 return no_proxy;
284 }
|
1 /*
2 * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include <windows.h>
27 #include <Winhttp.h>
28
29 #include "jni.h"
30 #include "jni_util.h"
31 #include "jvm.h"
32
33 #include "proxy_util.h"
34
35 #include "sun_net_spi_DefaultProxySelector.h"
36
37 /*
38 * These functions are used by the sun.net.spi.DefaultProxySelector class
39 * to access some platform specific settings.
40 * On Windows use WinHTTP functions to get the system settings.
41 */
42
43 /* Keep one static session for all requests. */
44 static HINTERNET session = NULL;
45
46 /*
47 * Class: sun_net_spi_DefaultProxySelector
48 * Method: init
49 * Signature: ()Z
50 */
51 JNIEXPORT jboolean JNICALL
52 Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
53
54 /*
55 * Get one WinHTTP session handle to initialize the WinHTTP internal data
56 * structures. Keep and use only this one for the whole life time.
57 */
58 session = WinHttpOpen(L"Only used internal", /* we need no real agent string here */
59 WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
60 WINHTTP_NO_PROXY_NAME,
61 WINHTTP_NO_PROXY_BYPASS,
62 0);
63 if (session == NULL) {
64 return JNI_FALSE;
65 }
66
67 if (!initJavaClass(env)) {
68 return JNI_FALSE;
69 }
70
71 return JNI_TRUE;
72 }
73
74
75 #define MAX_STR_LEN 1024
76
77 /* A linked list element for a proxy */
78 typedef struct list_item {
79 wchar_t *host;
80 int port;
81 struct list_item *next;
82 } list_item;
83
84 /* Free the linked list */
85 static void freeList(list_item *head) {
86 list_item *next = NULL;
87 list_item *current = head;
88 while (current != NULL) {
89 next = current->next;
90 free(current->host);
91 free(current);
92 current = next;
93 }
94 }
95
96
97 /*
98 * Creates a linked list of list_item elements that has to be freed later on.
99 * Returns the size of the array as int.
100 */
101 static int createProxyList(LPWSTR win_proxy, const WCHAR *pproto, list_item **head) {
102 static const wchar_t separators[] = L"\t\r\n ;";
103 list_item *current = NULL;
104 int nr_elems = 0;
105 wchar_t *context = NULL;
106 wchar_t *current_proxy = NULL;
107 BOOL error = FALSE;
108
109 /*
110 * The proxy server list contains one or more of the following strings
111 * separated by semicolons or whitespace:
112 * ([<scheme>=][<scheme>"://"]<server>[":"<port>])
113 */
114 current_proxy = wcstok_s(win_proxy, separators, &context);
115 while (current_proxy != NULL) {
116 LPWSTR pport;
117 LPWSTR phost;
118 int portVal = 0;
119 wchar_t *next_proxy = NULL;
120 list_item *proxy = NULL;
121 wchar_t* pos = NULL;
122
123 /* Filter based on the scheme, if there is one */
124 pos = wcschr(current_proxy, L'=');
125 if (pos) {
126 *pos = L'\0';
127 if (wcscmp(current_proxy, pproto) != 0) {
128 current_proxy = wcstok_s(NULL, separators, &context);
129 continue;
130 }
131 current_proxy = pos + 1;
132 }
133
134 /* Let's check for a scheme and ignore it. */
135 if ((phost = wcsstr(current_proxy, L"://")) != NULL) {
136 phost += 3;
137 } else {
138 phost = current_proxy;
139 }
140
141 /* Get the port */
142 pport = wcschr(phost, L':');
143 if (pport != NULL) {
144 *pport = 0;
145 pport++;
146 swscanf(pport, L"%d", &portVal);
147 }
148
149 proxy = (list_item *)malloc(sizeof(list_item));
150 if (proxy != NULL) {
151 proxy->next = NULL;
152 proxy->port = portVal;
153 proxy->host = _wcsdup(phost);
154
155 if (proxy->host != NULL) {
156 if (*head == NULL) {
157 *head = proxy; /* first elem */
158 }
159 if (current != NULL) {
160 current->next = proxy;
161 }
162 current = proxy;
163 nr_elems++;
164 } else {
165 free(proxy); /* cleanup */
166 }
167 }
168 /* goto next proxy if available... */
169 current_proxy = wcstok_s(NULL, separators, &context);
170 }
171 return nr_elems;
172 }
173
174
175
176 /*
177 * Class: sun_net_spi_DefaultProxySelector
178 * Method: getSystemProxies
179 * Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
180 */
181 JNIEXPORT jobjectArray JNICALL
182 Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
183 jobject this,
184 jstring proto,
185 jstring host)
186 {
187 jobjectArray proxy_array = NULL;
188 jobject type_proxy = NULL;
189 LPCWSTR lpProto;
190 LPCWSTR lpHost;
191 list_item *head = NULL;
192
193 BOOL use_auto_proxy = FALSE;
194 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_proxy_config;
195 WINHTTP_AUTOPROXY_OPTIONS auto_proxy_options;
196 WINHTTP_PROXY_INFO proxy_info;
197 LPWSTR win_proxy = NULL;
198 LPWSTR win_bypass_proxy = NULL;
199
200 memset(&ie_proxy_config, 0, sizeof(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG));
201 memset(&auto_proxy_options, 0, sizeof(WINHTTP_AUTOPROXY_OPTIONS));
202 memset(&proxy_info, 0, sizeof(WINHTTP_PROXY_INFO));
203
204 lpHost = (*env)->GetStringChars(env, host, NULL);
205 if (lpHost == NULL) {
206 if (!(*env)->ExceptionCheck(env))
207 JNU_ThrowOutOfMemoryError(env, NULL);
208 return NULL;
209 }
210
211 lpProto = (*env)->GetStringChars(env, proto, NULL);
212 if (lpProto == NULL) {
213 (*env)->ReleaseStringChars(env, host, lpHost);
214 if (!(*env)->ExceptionCheck(env))
215 JNU_ThrowOutOfMemoryError(env, NULL);
216 return NULL;
217 }
218
219 if (WinHttpGetIEProxyConfigForCurrentUser(&ie_proxy_config) == FALSE) {
220 /* cleanup and exit */
221 (*env)->ReleaseStringChars(env, host, lpHost);
222 (*env)->ReleaseStringChars(env, proto, lpProto);
223 return NULL;
224 }
225
226 if (ie_proxy_config.fAutoDetect) {
227 /* Windows uses WPAD */
228 auto_proxy_options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP |
229 WINHTTP_AUTO_DETECT_TYPE_DNS_A;
230 auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
231 auto_proxy_options.fAutoLogonIfChallenged = TRUE;
232 use_auto_proxy = TRUE;
233 } else if (ie_proxy_config.lpszAutoConfigUrl != NULL) {
234 /* Windows uses PAC file */
235 auto_proxy_options.lpszAutoConfigUrl = ie_proxy_config.lpszAutoConfigUrl;
236 auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
237 use_auto_proxy = TRUE;
238 } else if (ie_proxy_config.lpszProxy != NULL) {
239 /* Windows uses manually entered proxy. */
240 use_auto_proxy = FALSE;
241 win_bypass_proxy = ie_proxy_config.lpszProxyBypass;
242 win_proxy = ie_proxy_config.lpszProxy;
243 }
244
245 if (use_auto_proxy) {
246 WCHAR url[MAX_STR_LEN];
247 /* Create url for WinHttpGetProxyForUrl */
248 _snwprintf(url, sizeof(url) - 1, L"%s://%s", lpProto, lpHost);
249 /* Get proxy for URL from Windows */
250 use_auto_proxy = WinHttpGetProxyForUrl(session, &url[0], &auto_proxy_options, &proxy_info);
251 if (use_auto_proxy) {
252 win_proxy = proxy_info.lpszProxy;
253 win_bypass_proxy = proxy_info.lpszProxyBypass;
254 }
255 }
256
257 /* Check the bypass entry. */
258 if (NULL != win_bypass_proxy) {
259 /*
260 * From MSDN:
261 * The proxy bypass list contains one or more server names separated by
262 * semicolons or whitespace. The proxy bypass list can also contain the
263 * string "<local>" to indicate that all local intranet sites are
264 * bypassed. Local intranet sites are considered to be all servers that
265 * do not contain a period in their name.
266 */
267 wchar_t *context = NULL;
268 LPWSTR s = wcstok_s(win_bypass_proxy, L"; ", &context);
269
270 while (s != NULL) {
271 size_t maxlen = wcslen(s);
272 if (wcsncmp(s, lpHost, maxlen) == 0) {
273 /*
274 * The URL host name matches with one of the prefixes, use a
275 * direct connection.
276 */
277 goto noproxy;
278 }
279 if (wcsncmp(s, L"<local>", maxlen) == 0) {
280 /*
281 * All local intranet sites are bypassed - Microsoft consider all
282 * servers that do not contain a period in their name to be local.
283 */
284 if (wcschr(lpHost, '.') == NULL) {
285 goto noproxy;
286 }
287 }
288 s = wcstok_s(NULL, L"; ", &context);
289 }
290 }
291
292 if (win_proxy != NULL) {
293 wchar_t *context = NULL;
294 int defport = 0;
295 int nr_elems = 0;
296
297 /* Set the default port value & proxy type from protocol. */
298 if ((wcscmp(lpProto, L"http") == 0) ||
299 (wcscmp(lpProto, L"ftp") == 0) ||
300 (wcscmp(lpProto, L"gopher") == 0))
301 defport = 80;
302 if (wcscmp(lpProto, L"https") == 0)
303 defport = 443;
304 if (wcscmp(lpProto, L"socks") == 0) {
305 defport = 1080;
306 type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);
307 } else {
308 type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
309 }
310 if (type_proxy == NULL || (*env)->ExceptionCheck(env)) {
311 goto noproxy;
312 }
313
314 nr_elems = createProxyList(win_proxy, lpProto, &head);
315 if (nr_elems != 0 && head != NULL) {
316 int index = 0;
317 proxy_array = (*env)->NewObjectArray(env, nr_elems, proxy_class, NULL);
318 if (proxy_array == NULL || (*env)->ExceptionCheck(env)) {
319 goto noproxy;
320 }
321 while (head != NULL && index < nr_elems) {
322 jstring jhost;
323 jobject isa;
324 jobject proxy;
325
326 if (head->host != NULL && proxy_array != NULL) {
327 /* Let's create the appropriate Proxy object then. */
328 if (head->port == 0) {
329 head->port = defport;
330 }
331 jhost = (*env)->NewString(env, head->host, (jsize)wcslen(head->host));
332 if (jhost == NULL || (*env)->ExceptionCheck(env)) {
333 proxy_array = NULL;
334 }
335 isa = (*env)->CallStaticObjectMethod(env, isaddr_class,
336 isaddr_createUnresolvedID, jhost,
337 head->port);
338 if (isa == NULL || (*env)->ExceptionCheck(env)) {
339 proxy_array = NULL;
340 }
341 proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
342 if (proxy == NULL || (*env)->ExceptionCheck(env)) {
343 proxy_array = NULL;
344 }
345 (*env)->SetObjectArrayElement(env, proxy_array, index, proxy);
346 if ((*env)->ExceptionCheck(env)) {
347 proxy_array = NULL;
348 }
349 index++;
350 }
351 head = head->next;
352 }
353 }
354 }
355
356 noproxy:
357 if (head != NULL) {
358 freeList(head);
359 }
360 if (proxy_info.lpszProxy != NULL)
361 GlobalFree(proxy_info.lpszProxy);
362 if (proxy_info.lpszProxyBypass != NULL)
363 GlobalFree(proxy_info.lpszProxyBypass);
364 if (ie_proxy_config.lpszAutoConfigUrl != NULL)
365 GlobalFree(ie_proxy_config.lpszAutoConfigUrl);
366 if (ie_proxy_config.lpszProxy != NULL)
367 GlobalFree(ie_proxy_config.lpszProxy);
368 if (ie_proxy_config.lpszProxyBypass != NULL)
369 GlobalFree(ie_proxy_config.lpszProxyBypass);
370 if (lpHost != NULL)
371 (*env)->ReleaseStringChars(env, host, lpHost);
372 if (lpProto != NULL)
373 (*env)->ReleaseStringChars(env, proto, lpProto);
374
375 return proxy_array;
376 }
|