Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/macosx/native/libnet/DefaultProxySelector.c
41119 views
1
/*
2
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2017 SAP SE. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation. Oracle designates this
9
* particular file as subject to the "Classpath" exception as provided
10
* by Oracle in the LICENSE file that accompanied this code.
11
*
12
* This code is distributed in the hope that it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15
* version 2 for more details (a copy is included in the LICENSE file that
16
* accompanied this code).
17
*
18
* You should have received a copy of the GNU General Public License version
19
* 2 along with this work; if not, write to the Free Software Foundation,
20
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21
*
22
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23
* or visit www.oracle.com if you need additional information or have any
24
* questions.
25
*/
26
27
#include <string.h>
28
#include <CoreFoundation/CoreFoundation.h>
29
#include <CoreServices/CoreServices.h>
30
31
#include "jni.h"
32
#include "jni_util.h"
33
#include "jvm.h"
34
#include "jvm_md.h"
35
36
#include "proxy_util.h"
37
38
#include "sun_net_spi_DefaultProxySelector.h"
39
40
41
/**
42
* For more information on how to use the APIs in "CFProxySupport.h" see:
43
* https://developer.apple.com/legacy/library/samplecode/CFProxySupportTool/Introduction/Intro.html
44
*/
45
46
#define kResolveProxyRunLoopMode CFSTR("sun.net.spi.DefaultProxySelector")
47
48
#define BUFFER_SIZE 1024
49
50
/* Callback for CFNetworkExecuteProxyAutoConfigurationURL. */
51
static void proxyUrlCallback(void * client, CFArrayRef proxies, CFErrorRef error) {
52
/* client is a pointer to a CFTypeRef and holds either proxies or an error. */
53
CFTypeRef* resultPtr = (CFTypeRef *)client;
54
55
if (error != NULL) {
56
*resultPtr = CFRetain(error);
57
} else {
58
*resultPtr = CFRetain(proxies);
59
}
60
CFRunLoopStop(CFRunLoopGetCurrent());
61
}
62
63
/*
64
* Returns a new array of proxies containing all the given non-PAC proxies as
65
* well as the results of executing all the given PAC-based proxies, for the
66
* specified URL. 'proxies' is a list that may contain both PAC and non-PAC
67
* proxies.
68
*/
69
static CFArrayRef createExpandedProxiesArray(CFArrayRef proxies, CFURLRef url) {
70
71
CFIndex count;
72
CFIndex index;
73
CFMutableArrayRef expandedProxiesArray;
74
75
expandedProxiesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
76
if (expandedProxiesArray == NULL)
77
return NULL;
78
79
/* Iterate over the array of proxies */
80
count = CFArrayGetCount(proxies);
81
for (index = 0; index < count ; index++) {
82
CFDictionaryRef currentProxy;
83
CFStringRef proxyType;
84
85
currentProxy = (CFDictionaryRef) CFArrayGetValueAtIndex(proxies, index);
86
if(currentProxy == NULL) {
87
CFRelease(expandedProxiesArray);
88
return NULL;
89
}
90
proxyType = (CFStringRef) CFDictionaryGetValue(currentProxy, kCFProxyTypeKey);
91
if (proxyType == NULL) {
92
CFRelease(expandedProxiesArray);
93
return NULL;
94
}
95
96
if (!CFEqual(proxyType, kCFProxyTypeAutoConfigurationURL)) {
97
/* Non-PAC entry, just copy it to the new array */
98
CFArrayAppendValue(expandedProxiesArray, currentProxy);
99
} else {
100
/* PAC-based URL, execute its script append its results */
101
CFRunLoopSourceRef runLoop;
102
CFURLRef scriptURL;
103
CFTypeRef result = NULL;
104
CFStreamClientContext context = { 0, &result, NULL, NULL, NULL };
105
CFTimeInterval timeout = 5;
106
107
scriptURL = CFDictionaryGetValue(currentProxy, kCFProxyAutoConfigurationURLKey);
108
109
runLoop = CFNetworkExecuteProxyAutoConfigurationURL(scriptURL, url, proxyUrlCallback,
110
&context);
111
if (runLoop != NULL) {
112
/*
113
* Despite the fact that CFNetworkExecuteProxyAutoConfigurationURL has
114
* neither a "Create" nor a "Copy" in the name, we are required to
115
* release the return CFRunLoopSourceRef <rdar://problem/5533931>.
116
*/
117
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoop, kResolveProxyRunLoopMode);
118
CFRunLoopRunInMode(kResolveProxyRunLoopMode, timeout, false);
119
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoop, kResolveProxyRunLoopMode);
120
121
/*
122
* Once the runloop returns, there will be either an error result or
123
* a proxies array result. Do the appropriate thing with that result.
124
*/
125
if (result != NULL) {
126
if (CFGetTypeID(result) == CFArrayGetTypeID()) {
127
/*
128
* Append the new array from the PAC list - it contains
129
* only non-PAC entries.
130
*/
131
CFArrayAppendArray(expandedProxiesArray, result,
132
CFRangeMake(0, CFArrayGetCount(result)));
133
}
134
CFRelease(result);
135
}
136
CFRelease(runLoop);
137
}
138
}
139
}
140
return expandedProxiesArray;
141
}
142
143
144
/*
145
* Class: sun_net_spi_DefaultProxySelector
146
* Method: init
147
* Signature: ()Z
148
*/
149
JNIEXPORT jboolean JNICALL
150
Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
151
if (!initJavaClass(env)) {
152
return JNI_FALSE;
153
}
154
return JNI_TRUE;
155
}
156
157
158
/*
159
* Class: sun_net_spi_DefaultProxySelector
160
* Method: getSystemProxies
161
* Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
162
*/
163
JNIEXPORT jobjectArray JNICALL
164
Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
165
jobject this,
166
jstring proto,
167
jstring host)
168
{
169
CFDictionaryRef proxyDicRef = NULL;
170
CFURLRef urlRef = NULL;
171
bool proxyFound = false;
172
jobjectArray proxyArray = NULL;
173
const char *cproto;
174
const char *chost;
175
176
/* Get system proxy settings */
177
proxyDicRef = CFNetworkCopySystemProxySettings();
178
if (proxyDicRef == NULL) {
179
return NULL;
180
}
181
182
/* Create CFURLRef from proto and host */
183
cproto = (*env)->GetStringUTFChars(env, proto, NULL);
184
if (cproto != NULL) {
185
chost = (*env)->GetStringUTFChars(env, host, NULL);
186
if (chost != NULL) {
187
char* uri = NULL;
188
size_t protoLen = 0;
189
size_t hostLen = 0;
190
191
protoLen = strlen(cproto);
192
hostLen = strlen(chost);
193
194
/* Construct the uri, cproto + "://" + chost */
195
uri = malloc(protoLen + hostLen + 4);
196
if (uri != NULL) {
197
memcpy(uri, cproto, protoLen);
198
memcpy(uri + protoLen, "://", 3);
199
memcpy(uri + protoLen + 3, chost, hostLen + 1);
200
201
urlRef = CFURLCreateWithBytes(NULL, (const UInt8 *) uri, strlen(uri),
202
kCFStringEncodingUTF8, NULL);
203
free(uri);
204
}
205
(*env)->ReleaseStringUTFChars(env, host, chost);
206
}
207
(*env)->ReleaseStringUTFChars(env, proto, cproto);
208
}
209
if (urlRef != NULL) {
210
CFArrayRef urlProxyArrayRef = CFNetworkCopyProxiesForURL(urlRef, proxyDicRef);
211
if (urlProxyArrayRef != NULL) {
212
CFIndex count;
213
CFIndex index;
214
215
CFArrayRef expandedProxyArray = createExpandedProxiesArray(urlProxyArrayRef, urlRef);
216
CFRelease(urlProxyArrayRef);
217
218
if (expandedProxyArray == NULL) {
219
CFRelease(urlRef);
220
CFRelease(proxyDicRef);
221
return NULL;
222
}
223
224
count = CFArrayGetCount(expandedProxyArray);
225
226
proxyArray = (*env)->NewObjectArray(env, count, proxy_class, NULL);
227
if (proxyArray != NULL || (*env)->ExceptionCheck(env)) {
228
/* Iterate over the expanded array of proxies */
229
for (index = 0; index < count ; index++) {
230
CFDictionaryRef currentProxy;
231
CFStringRef proxyType;
232
jobject proxy = NULL;
233
234
currentProxy = (CFDictionaryRef) CFArrayGetValueAtIndex(expandedProxyArray,
235
index);
236
proxyType = (CFStringRef) CFDictionaryGetValue(currentProxy, kCFProxyTypeKey);
237
if (CFEqual(proxyType, kCFProxyTypeNone)) {
238
/* This entry states no proxy, therefore just add a NO_PROXY object. */
239
proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID);
240
} else {
241
/*
242
* Create a proxy object for this entry.
243
* Differentiate between SOCKS and HTTP type.
244
*/
245
jfieldID typeID = ptype_httpID;
246
if (CFEqual(proxyType, kCFProxyTypeSOCKS)) {
247
typeID = ptype_socksID;
248
}
249
CFNumberRef portNumberRef = (CFNumberRef)CFDictionaryGetValue(currentProxy,
250
(const void*)kCFProxyPortNumberKey);
251
if (portNumberRef != NULL) {
252
int port = 0;
253
if (CFNumberGetValue(portNumberRef, kCFNumberSInt32Type, &port)) {
254
CFStringRef hostNameRef = (CFStringRef)CFDictionaryGetValue(
255
currentProxy, (const void*)kCFProxyHostNameKey);
256
if (hostNameRef != NULL) {
257
char hostNameBuffer[BUFFER_SIZE];
258
if (CFStringGetCString(hostNameRef, hostNameBuffer,
259
BUFFER_SIZE, kCFStringEncodingUTF8)) {
260
proxy = createProxy(env, typeID, &hostNameBuffer[0], port);
261
}
262
}
263
}
264
}
265
}
266
if (proxy == NULL || (*env)->ExceptionCheck(env)) {
267
proxyArray = NULL;
268
break;
269
}
270
(*env)->SetObjectArrayElement(env, proxyArray, index, proxy);
271
if ((*env)->ExceptionCheck(env)) {
272
proxyArray = NULL;
273
break;
274
}
275
}
276
}
277
CFRelease(expandedProxyArray);
278
}
279
CFRelease(urlRef);
280
}
281
CFRelease(proxyDicRef);
282
283
return proxyArray;
284
}
285
286