File system-proxies.patch of Package mozilla-xulrunner181 (Revision e78671003c7f81a36f7a42da57b84858)
Currently displaying revision e78671003c7f81a36f7a42da57b84858, show latest
x
1
Index: netwerk/base/public/nsISystemProxySettings.idl
2
================================================================================
3
--- allmakefiles.sh
4
+++ allmakefiles.sh
5
6
toolkit/components/downloads/src/Makefile
7
toolkit/components/filepicker/Makefile
8
toolkit/components/gnome/Makefile
9
+toolkit/components/unixproxy/Makefile
10
toolkit/components/help/Makefile
11
toolkit/components/history/Makefile
12
toolkit/components/history/public/Makefile
13
--- netwerk/base/public/Makefile.in
14
+++ netwerk/base/public/Makefile.in
15
16
nsIStreamTransportService.idl \
17
nsIStreamLoader.idl \
18
nsISyncStreamListener.idl \
19
+ nsISystemProxySettings.idl \
20
nsIUnicharStreamLoader.idl \
21
nsIStandardURL.idl \
22
nsIURLParser.idl \
23
--- netwerk/base/public/nsISystemProxySettings.idl
24
+++ netwerk/base/public/nsISystemProxySettings.idl
25
26
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
27
+/* ***** BEGIN LICENSE BLOCK *****
28
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
29
+ *
30
+ * The contents of this file are subject to the Mozilla Public License Version
31
+ * 1.1 (the "License"); you may not use this file except in compliance with
32
+ * the License. You may obtain a copy of the License at
33
+ * http://www.mozilla.org/MPL/
34
+ *
35
+ * Software distributed under the License is distributed on an "AS IS" basis,
36
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
37
+ * for the specific language governing rights and limitations under the
38
+ * License.
39
+ *
40
+ * The Original Code is Novell code.
41
+ *
42
+ * The Initial Developer of the Original Code is Novell.
43
+ * Portions created by the Initial Developer are Copyright (C) 2005
44
+ * the Initial Developer. All Rights Reserved.
45
+ *
46
+ * Contributor(s):
47
+ * Robert O'Callahan (rocallahan@novell.com)
48
+ *
49
+ * Alternatively, the contents of this file may be used under the terms of
50
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
51
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
52
+ * in which case the provisions of the GPL or the LGPL are applicable instead
53
+ * of those above. If you wish to allow use of your version of this file only
54
+ * under the terms of either the GPL or the LGPL, and not to allow others to
55
+ * use your version of this file under the terms of the MPL, indicate your
56
+ * decision by deleting the provisions above and replace them with the notice
57
+ * and other provisions required by the GPL or the LGPL. If you do not delete
58
+ * the provisions above, a recipient may use your version of this file under
59
+ * the terms of any one of the MPL, the GPL or the LGPL.
60
+ *
61
+ * ***** END LICENSE BLOCK ***** */
62
+
63
+#include "nsISupports.idl"
64
+#include "nsIURI.idl"
65
+
66
+%{C++
67
+#define NS_SYSTEMPROXYSETTINGS_CONTRACTID "@mozilla.org/system-proxy-settings;1"
68
+%}
69
+
70
+/**
71
+ * This interface allows the proxy code to use platform-specific proxy
72
+ * settings when the proxy preference is set to "automatic discovery". If it can
73
+ * load a service with the above contract ID, it will use it to determine the
74
+ * PAC file name. If no PAC file is specified then the service itself will behave
75
+ * like a PAC file.
76
+ */
77
+[scriptable, uuid(a9f3ae38-b769-4e0b-9317-578388e326c9)]
78
+interface nsISystemProxySettings : nsISupports
79
+{
80
+ /**
81
+ * If non-empty, use this PAC file. If empty, call getProxyForURI instead.
82
+ */
83
+ readonly attribute AUTF8String PACURI;
84
+
85
+ /**
86
+ * See nsIProxyAutoConfig::getProxyForURI; this function behaves exactly
87
+ * the same way.
88
+ */
89
+ ACString getProxyForURI(in nsIURI aURI);
90
+};
91
--- netwerk/base/src/nsPACMan.h
92
+++ netwerk/base/src/nsPACMan.h
93
94
*/
95
PRBool IsLoading() { return mLoader != nsnull; }
96
97
+ /**
98
+ * Returns true if the given URI matches the URI of our PAC file.
99
+ */
100
+ PRBool IsPACURI(nsIURI *uri) {
101
+ PRBool result;
102
+ return mPACURI && NS_SUCCEEDED(mPACURI->Equals(uri, &result)) && result;
103
+ }
104
+
105
private:
106
NS_DECL_NSISTREAMLOADEROBSERVER
107
NS_DECL_NSIINTERFACEREQUESTOR
108
109
void OnLoadFailure();
110
111
/**
112
- * Returns true if the given URI matches the URI of our PAC file.
113
- */
114
- PRBool IsPACURI(nsIURI *uri) {
115
- PRBool result;
116
- return mPACURI && NS_SUCCEEDED(mPACURI->Equals(uri, &result)) && result;
117
- }
118
-
119
- /**
120
* Event fu for calling StartLoading asynchronously.
121
*/
122
PR_STATIC_CALLBACK(void *) LoadEvent_Handle(PLEvent *);
123
--- netwerk/base/src/nsProtocolProxyService.cpp
124
+++ netwerk/base/src/nsProtocolProxyService.cpp
125
126
mProxyConfig = NS_STATIC_CAST(ProxyConfig, type);
127
reloadPAC = PR_TRUE;
128
}
129
+
130
+ if (mProxyConfig == eProxyConfig_System) {
131
+ mSystemProxySettings = do_GetService(NS_SYSTEMPROXYSETTINGS_CONTRACTID);
132
+ } else {
133
+ mSystemProxySettings = nsnull;
134
+ }
135
}
136
137
if (!pref || !strcmp(pref, "network.proxy.http"))
138
139
LoadHostFilters(tempString.get());
140
}
141
142
- // We're done if not using PAC or WPAD
143
- if (mProxyConfig != eProxyConfig_PAC && mProxyConfig != eProxyConfig_WPAD)
144
+ // We're done if not using something that could give us a PAC URL
145
+ // (PAC, WPAD or System)
146
+ if (mProxyConfig != eProxyConfig_PAC && mProxyConfig != eProxyConfig_WPAD &&
147
+ mProxyConfig != eProxyConfig_System)
148
return;
149
150
// OK, we need to reload the PAC file if:
151
152
if (mProxyConfig == eProxyConfig_PAC) {
153
prefBranch->GetCharPref("network.proxy.autoconfig_url",
154
getter_Copies(tempString));
155
- }
156
- else if (mProxyConfig == eProxyConfig_WPAD) {
157
+ } else {
158
// We diverge from the WPAD spec here in that we don't walk the
159
// hosts's FQDN, stripping components until we hit a TLD. Doing so
160
// is dangerous in the face of an incomplete list of TLDs, and TLDs
161
// get added over time. We could consider doing only a single
162
// substitution of the first component, if that proves to help
163
// compatibility.
164
- tempString.AssignLiteral("http://wpad/wpad.dat");
165
+ if (mSystemProxySettings)
166
+ mSystemProxySettings->GetPACURI(tempString);
167
+ else
168
+ tempString.AssignLiteral("http://wpad/wpad.dat");
169
+ }
170
+ if (!tempString.IsEmpty()) {
171
+ ConfigureFromPAC(tempString);
172
}
173
- ConfigureFromPAC(tempString);
174
}
175
}
176
177
178
return NS_ERROR_OUT_OF_MEMORY;
179
}
180
181
- mFailedProxies.Clear();
182
-
183
nsCOMPtr<nsIURI> pacURI;
184
nsresult rv = NS_NewURI(getter_AddRefs(pacURI), spec);
185
if (NS_FAILED(rv))
186
return rv;
187
188
+ if (mPACMan->IsPACURI(pacURI))
189
+ return NS_OK;
190
+
191
+ mFailedProxies.Clear();
192
+
193
return mPACMan->LoadPACFromURI(pacURI);
194
}
195
196
197
nsresult aStatus,
198
nsIProxyInfo **aResult)
199
{
200
- // We only support failover when a PAC file is configured.
201
- if (mProxyConfig != eProxyConfig_PAC && mProxyConfig != eProxyConfig_WPAD)
202
+ // We only support failover when a PAC file is configured, either
203
+ // directly or via system settings
204
+ if (mProxyConfig != eProxyConfig_PAC && mProxyConfig != eProxyConfig_WPAD &&
205
+ mProxyConfig != eProxyConfig_System)
206
return NS_ERROR_NOT_AVAILABLE;
207
208
// Verify that |aProxy| is one of our nsProxyInfo objects.
209
210
if (!(info.flags & nsIProtocolHandler::ALLOWS_PROXY))
211
return NS_OK; // Can't proxy this (filters may not override)
212
213
+ if (mSystemProxySettings) {
214
+ nsCAutoString PACURI;
215
+ if (NS_SUCCEEDED(mSystemProxySettings->GetPACURI(PACURI)) &&
216
+ !PACURI.IsEmpty()) {
217
+ // Switch to new PAC file if that setting has changed. If the setting
218
+ // hasn't changed, ConfigureFromPAC will exit early.
219
+ nsresult rv = ConfigureFromPAC(PACURI);
220
+ if (NS_FAILED(rv))
221
+ return rv;
222
+ } else {
223
+ nsCAutoString proxy;
224
+ nsresult rv = mSystemProxySettings->GetProxyForURI(uri, proxy);
225
+ if (NS_SUCCEEDED(rv)) {
226
+ ProcessPACString(proxy, result);
227
+ return NS_OK;
228
+ }
229
+ // no proxy, stop search
230
+ return NS_OK;
231
+ }
232
+ }
233
+
234
// if proxies are enabled and this host:port combo is supposed to use a
235
// proxy, check for a proxy.
236
if (mProxyConfig == eProxyConfig_Direct ||
237
(mProxyConfig == eProxyConfig_Manual &&
238
!CanUseProxy(uri, info.defaultPort)))
239
return NS_OK;
240
-
241
+
242
// Proxy auto config magic...
243
- if (mProxyConfig == eProxyConfig_PAC || mProxyConfig == eProxyConfig_WPAD) {
244
+ if (mProxyConfig == eProxyConfig_PAC || mProxyConfig == eProxyConfig_WPAD ||
245
+ mProxyConfig == eProxyConfig_System) {
246
// Do not query PAC now.
247
*usePAC = PR_TRUE;
248
return NS_OK;
249
--- netwerk/base/src/nsProtocolProxyService.h
250
+++ netwerk/base/src/nsProtocolProxyService.h
251
252
#include "nsPIProtocolProxyService.h"
253
#include "nsIProtocolProxyFilter.h"
254
#include "nsIProxyAutoConfig.h"
255
+#include "nsISystemProxySettings.h"
256
#include "nsIProxyInfo.h"
257
#include "nsIObserver.h"
258
#include "nsDataHashtable.h"
259
260
eProxyConfig_PAC,
261
eProxyConfig_Direct4x,
262
eProxyConfig_WPAD,
263
+ eProxyConfig_System, // use system proxy settings if available, otherwise WPAD
264
eProxyConfig_Last
265
};
266
267
268
PRBool mSOCKSProxyRemoteDNS;
269
270
nsRefPtr<nsPACMan> mPACMan; // non-null if we are using PAC
271
+ nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
272
273
PRTime mSessionStart;
274
nsFailedProxyTable mFailedProxies;
275
Index: Makefile.in
276
===================================================================
277
RCS file: /cvsroot/mozilla/Makefile.in,v
278
retrieving revision 1.299.2.18
279
diff -u -p -6 -r1.299.2.18 Makefile.in
280
--- Makefile.in 14 Sep 2006 18:07:02 -0000 1.299.2.18
281
+++ Makefile.in 27 Nov 2006 19:04:14 -0000
282
283
endif
284
285
ifndef MINIMO
286
ifdef MOZ_XUL_APP
287
ifdef MOZ_ENABLE_GTK2
288
tier_50_dirs += toolkit/components/gnome
289
+tier_50_dirs += toolkit/components/unixproxy
290
endif
291
endif
292
endif
293
294
ifdef MOZ_LEAKY
295
tier_50_dirs += tools/leaky
296
--- toolkit/components/unixproxy/Makefile.in.orig 2006-11-27 21:25:50.000000000 +0100
297
+++ toolkit/components/unixproxy/Makefile.in 2006-11-27 21:26:18.000000000 +0100
298
299
+# ***** BEGIN LICENSE BLOCK *****
300
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
301
+#
302
+# The contents of this file are subject to the Mozilla Public License Version
303
+# 1.1 (the "License"); you may not use this file except in compliance with
304
+# the License. You may obtain a copy of the License at
305
+# http://www.mozilla.org/MPL/
306
+#
307
+# Software distributed under the License is distributed on an "AS IS" basis,
308
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
309
+# for the specific language governing rights and limitations under the
310
+# License.
311
+#
312
+# The Original Code is the Mozilla GNOME integration code.
313
+#
314
+# The Initial Developer of the Original Code is
315
+# IBM Corporation.
316
+# Portions created by the Initial Developer are Copyright (C) 2004
317
+# the Initial Developer. All Rights Reserved.
318
+#
319
+# Contributor(s):
320
+# Brian Ryner <bryner@brianryner.com>
321
+#
322
+# Alternatively, the contents of this file may be used under the terms of
323
+# either the GNU General Public License Version 2 or later (the "GPL"), or
324
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
325
+# in which case the provisions of the GPL or the LGPL are applicable instead
326
+# of those above. If you wish to allow use of your version of this file only
327
+# under the terms of either the GPL or the LGPL, and not to allow others to
328
+# use your version of this file under the terms of the MPL, indicate your
329
+# decision by deleting the provisions above and replace them with the notice
330
+# and other provisions required by the GPL or the LGPL. If you do not delete
331
+# the provisions above, a recipient may use your version of this file under
332
+# the terms of any one of the MPL, the GPL or the LGPL.
333
+#
334
+# ***** END LICENSE BLOCK *****
335
+
336
+DEPTH = ../../..
337
+topsrcdir = @top_srcdir@
338
+srcdir = @srcdir@
339
+VPATH = @srcdir@
340
+
341
+include $(DEPTH)/config/autoconf.mk
342
+
343
+MODULE = unixproxy
344
+MOZILLA_INTERNAL_API = 1
345
+
346
+REQUIRES = \
347
+ xpcom \
348
+ string \
349
+ necko \
350
+ mozgnome \
351
+ $(NULL)
352
+
353
+CPPSRCS = \
354
+ nsUnixSystemProxySettings.cpp \
355
+ $(NULL)
356
+
357
+LIBRARY_NAME = unixproxy
358
+IS_COMPONENT = 1
359
+FORCE_SHARED_LIB = 1
360
+
361
+EXTRA_DSO_LDOPTS += \
362
+ $(MOZ_COMPONENT_LIBS) \
363
+ $(NULL)
364
+
365
+include $(topsrcdir)/config/rules.mk
366
Index: toolkit/components/gnome/nsGConfService.cpp
367
===================================================================
368
RCS file: /cvsroot/mozilla/toolkit/components/gnome/Attic/nsGConfService.cpp,v
369
retrieving revision 1.2
370
diff -u -p -6 -r1.2 nsGConfService.cpp
371
--- toolkit/components/gnome/nsGConfService.cpp 15 Jul 2004 22:51:19 -0000 1.2
372
+++ toolkit/components/gnome/nsGConfService.cpp 29 May 2007 05:42:27 -0000
373
374
return NS_ERROR_FAILURE;
375
}
376
377
return NS_OK;
378
}
379
380
+class StringListEnumerator : public nsIUTF8StringEnumerator
381
+{
382
+public:
383
+ NS_DECL_ISUPPORTS
384
+ NS_DECL_NSIUTF8STRINGENUMERATOR
385
+
386
+ StringListEnumerator(GSList* aList) : mList(aList), mNext(aList) {}
387
+ virtual ~StringListEnumerator() {
388
+ g_slist_free(mList);
389
+ }
390
+
391
+private:
392
+ GSList* mList;
393
+ GSList* mNext;
394
+};
395
+
396
+NS_IMPL_ISUPPORTS1(StringListEnumerator, nsIUTF8StringEnumerator)
397
+
398
+NS_IMETHODIMP
399
+StringListEnumerator::HasMore(PRBool* aResult)
400
+{
401
+ NS_PRECONDITION(aResult, "null ptr");
402
+ *aResult = mNext != nsnull;
403
+ return NS_OK;
404
+}
405
+
406
+NS_IMETHODIMP
407
+StringListEnumerator::GetNext(nsACString& aResult)
408
+{
409
+ if (!mNext)
410
+ return NS_ERROR_UNEXPECTED;
411
+ aResult.Assign(NS_STATIC_CAST(char*, mNext->data));
412
+ mNext = mNext->next;
413
+ return NS_OK;
414
+}
415
+
416
+NS_IMETHODIMP
417
+nsGConfService::GetStringList(const nsACString &aKey,
418
+ nsIUTF8StringEnumerator** aResult)
419
+{
420
+ GError* error = nsnull;
421
+ GSList* list = gconf_client_get_list(mClient, PromiseFlatCString(aKey).get(),
422
+ GCONF_VALUE_STRING, &error);
423
+ if (error) {
424
+ g_error_free(error);
425
+ return NS_ERROR_FAILURE;
426
+ }
427
+
428
+ StringListEnumerator* enumerator = new StringListEnumerator(list);
429
+ if (!enumerator) {
430
+ g_slist_free(list);
431
+ return NS_ERROR_OUT_OF_MEMORY;
432
+ }
433
+
434
+ NS_ADDREF(*aResult = enumerator);
435
+ return NS_OK;
436
+}
437
+
438
NS_IMETHODIMP
439
nsGConfService::SetBool(const nsACString &aKey, PRBool aValue)
440
{
441
PRBool res = gconf_client_set_bool(mClient, PromiseFlatCString(aKey).get(),
442
aValue, nsnull);
443
444
Index: toolkit/components/gnome/nsIGConfService.idl
445
===================================================================
446
RCS file: /cvsroot/mozilla/toolkit/components/gnome/Attic/nsIGConfService.idl,v
447
retrieving revision 1.2
448
diff -u -p -6 -r1.2 nsIGConfService.idl
449
--- toolkit/components/gnome/nsIGConfService.idl 15 Jul 2004 22:51:19 -0000 1.2
450
+++ toolkit/components/gnome/nsIGConfService.idl 29 May 2007 05:42:52 -0000
451
452
* the provisions above, a recipient may use your version of this file under
453
* the terms of any one of the MPL, the GPL or the LGPL.
454
*
455
* ***** END LICENSE BLOCK ***** */
456
457
#include "nsISupports.idl"
458
+#include "nsIStringEnumerator.idl"
459
460
[scriptable, uuid(01ac7b2e-c07c-465f-b35c-542eaef420a9)]
461
interface nsIGConfService : nsISupports
462
{
463
/* Basic registry access */
464
boolean getBool(in AUTF8String key);
465
AUTF8String getString(in AUTF8String key);
466
long getInt(in AUTF8String key);
467
float getFloat(in AUTF8String key);
468
+ nsIUTF8StringEnumerator getStringList(in AUTF8String key);
469
470
void setBool(in AUTF8String key, in boolean value);
471
void setString(in AUTF8String key, in AUTF8String value);
472
void setInt(in AUTF8String key, in long value);
473
void setFloat(in AUTF8String key, in float value);
474
475
--- toolkit/components/unixproxy/nsUnixSystemProxySettings.cpp.orig 2007-05-29 07:45:58.000000000 +0200
476
+++ toolkit/components/unixproxy/nsUnixSystemProxySettings.cpp 2007-05-29 08:37:45.000000000 +0200
477
478
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
479
+/* ***** BEGIN LICENSE BLOCK *****
480
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
481
+ *
482
+ * The contents of this file are subject to the Mozilla Public License Version
483
+ * 1.1 (the "License"); you may not use this file except in compliance with
484
+ * the License. You may obtain a copy of the License at
485
+ * http://www.mozilla.org/MPL/
486
+ *
487
+ * Software distributed under the License is distributed on an "AS IS" basis,
488
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
489
+ * for the specific language governing rights and limitations under the
490
+ * License.
491
+ *
492
+ * The Original Code is mozilla.org code.
493
+ *
494
+ * The Initial Developer of the Original Code is
495
+ * Netscape Communications Corporation.
496
+ * Portions created by the Initial Developer are Copyright (C) 1998
497
+ * the Initial Developer. All Rights Reserved.
498
+ *
499
+ * Contributor(s):
500
+ * Robert O'Callahan (rocallahan@novell.com)
501
+ *
502
+ * Alternatively, the contents of this file may be used under the terms of
503
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
504
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
505
+ * in which case the provisions of the GPL or the LGPL are applicable instead
506
+ * of those above. If you wish to allow use of your version of this file only
507
+ * under the terms of either the GPL or the LGPL, and not to allow others to
508
+ * use your version of this file under the terms of the MPL, indicate your
509
+ * decision by deleting the provisions above and replace them with the notice
510
+ * and other provisions required by the GPL or the LGPL. If you do not delete
511
+ * the provisions above, a recipient may use your version of this file under
512
+ * the terms of any one of the MPL, the GPL or the LGPL.
513
+ *
514
+ * ***** END LICENSE BLOCK ***** */
515
+
516
+#include "nsISystemProxySettings.h"
517
+#include "nsIGenericFactory.h"
518
+#include "nsIServiceManager.h"
519
+#include "nsIGConfService.h"
520
+#include "nsIURI.h"
521
+#include "nsReadableUtils.h"
522
+#include "nsArray.h"
523
+#include "prnetdb.h"
524
+#include "prenv.h"
525
+#include "nsPrintfCString.h"
526
+#include "nsNetUtil.h"
527
+
528
+class nsUnixSystemProxySettings : public nsISystemProxySettings {
529
+public:
530
+ NS_DECL_ISUPPORTS
531
+ NS_DECL_NSISYSTEMPROXYSETTINGS
532
+
533
+ nsUnixSystemProxySettings() {}
534
+ nsresult Init();
535
+
536
+private:
537
+ ~nsUnixSystemProxySettings() {}
538
+
539
+ nsCOMPtr<nsIGConfService> mGConf;
540
+};
541
+
542
+NS_IMPL_ISUPPORTS1(nsUnixSystemProxySettings, nsISystemProxySettings)
543
+
544
+nsresult
545
+nsUnixSystemProxySettings::Init()
546
+{
547
+ // If this is a GNOME session, load gconf and try to use its preferences.
548
+ // If gconf is not available (which would be stupid) we'll proceed as if this
549
+ // was not a GNOME session, using *_PROXY environment variables.
550
+ const char* sessionType = PR_GetEnv("DESKTOP_SESSION");
551
+ if (sessionType && !strcmp(sessionType, "gnome")) {
552
+ mGConf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
553
+ }
554
+ return NS_OK;
555
+}
556
+
557
+static PRBool
558
+IsProxyMode(nsIGConfService* aGConf, const char* aMode)
559
+{
560
+ nsCAutoString mode;
561
+ return NS_SUCCEEDED(aGConf->GetString(NS_LITERAL_CSTRING("/system/proxy/mode"), mode)) &&
562
+ mode.EqualsASCII(aMode);
563
+}
564
+
565
+nsresult
566
+nsUnixSystemProxySettings::GetPACURI(nsACString& aResult)
567
+{
568
+ if (!mGConf || !IsProxyMode(mGConf, "auto"))
569
+ return NS_ERROR_FAILURE;
570
+ return mGConf->GetString(NS_LITERAL_CSTRING("/system/proxy/autoconfig_url"),
571
+ aResult);
572
+}
573
+
574
+static PRBool
575
+IsInNoProxyList(const nsACString& aHost, PRInt32 aPort, const char* noProxyVal)
576
+{
577
+ NS_ASSERTION(aPort >= 0, "Negative port?");
578
+
579
+ nsCAutoString noProxy(noProxyVal);
580
+ if (noProxy.EqualsLiteral("*"))
581
+ return PR_TRUE;
582
+
583
+ noProxy.StripWhitespace();
584
+
585
+ nsReadingIterator<char> pos;
586
+ nsReadingIterator<char> end;
587
+ noProxy.BeginReading(pos);
588
+ noProxy.EndReading(end);
589
+ while (pos != end) {
590
+ nsReadingIterator<char> last = pos;
591
+ nsReadingIterator<char> nextPos;
592
+ if (FindCharInReadable(',', last, end)) {
593
+ nextPos = last;
594
+ ++nextPos;
595
+ } else {
596
+ last = end;
597
+ nextPos = end;
598
+ }
599
+
600
+ nsReadingIterator<char> colon = pos;
601
+ PRInt32 port = -1;
602
+ if (FindCharInReadable(':', colon, last)) {
603
+ ++colon;
604
+ nsDependentCSubstring portStr(colon, last);
605
+ nsCAutoString portStr2(portStr);
606
+ PRInt32 err;
607
+ port = portStr2.ToInteger(&err);
608
+ if (err != 0) {
609
+ port = -2; // don't match any port, so we ignore this pattern
610
+ }
611
+ --colon;
612
+ } else {
613
+ colon = last;
614
+ }
615
+
616
+ if (port == -1 || port == aPort) {
617
+ nsDependentCSubstring hostStr(pos, colon);
618
+ if (StringEndsWith(aHost, hostStr, nsCaseInsensitiveCStringComparator()))
619
+ return PR_TRUE;
620
+ }
621
+
622
+ pos = nextPos;
623
+ }
624
+
625
+ return PR_FALSE;
626
+}
627
+
628
+static void SetProxyResult(const char* aType, const nsACString& aHost,
629
+ PRInt32 aPort, nsACString& aResult)
630
+{
631
+ aResult.AppendASCII(aType);
632
+ aResult.Append(' ');
633
+ aResult.Append(aHost);
634
+ aResult.Append(':');
635
+ aResult.Append(nsPrintfCString("%d", aPort));
636
+}
637
+
638
+static nsresult
639
+GetProxyForURIFromEnvironment(const nsACString& aScheme,
640
+ const nsACString& aHost,
641
+ PRInt32 aPort,
642
+ nsACString& aResult)
643
+{
644
+ nsCAutoString envVar;
645
+ envVar.Append(aScheme);
646
+ envVar.AppendLiteral("_proxy");
647
+ const char* proxyVal = PR_GetEnv(envVar.get());
648
+ if (!proxyVal) {
649
+ proxyVal = PR_GetEnv("all_proxy");
650
+ if (!proxyVal) {
651
+ // Return failure so that the caller can detect the failure and
652
+ // fall back to other proxy detection (e.g., WPAD)
653
+ return NS_ERROR_FAILURE;
654
+ }
655
+ }
656
+
657
+ const char* noProxyVal = PR_GetEnv("no_proxy");
658
+ if (noProxyVal && IsInNoProxyList(aHost, aPort, noProxyVal)) {
659
+ aResult.AppendLiteral("DIRECT");
660
+ return NS_OK;
661
+ }
662
+
663
+ // Use our URI parser to crack the proxy URI
664
+ nsCOMPtr<nsIURI> proxyURI;
665
+ nsresult rv = NS_NewURI(getter_AddRefs(proxyURI), proxyVal);
666
+ if (NS_FAILED(rv))
667
+ return rv;
668
+
669
+ // Is there a way to specify "socks://" or something in these environment
670
+ // variables? I can't find any documentation.
671
+ PRBool isHTTP;
672
+ rv = proxyURI->SchemeIs("http", &isHTTP);
673
+ if (NS_FAILED(rv))
674
+ return rv;
675
+ if (!isHTTP)
676
+ return NS_ERROR_FAILURE;
677
+
678
+ nsCAutoString proxyHost;
679
+ rv = proxyURI->GetHost(proxyHost);
680
+ if (NS_FAILED(rv))
681
+ return rv;
682
+ PRInt32 proxyPort;
683
+ rv = proxyURI->GetPort(&proxyPort);
684
+ if (NS_FAILED(rv))
685
+ return rv;
686
+
687
+ SetProxyResult("PROXY", proxyHost, proxyPort, aResult);
688
+ return NS_OK;
689
+}
690
+
691
+static nsresult
692
+SetProxyResultFromGConf(nsIGConfService* aGConf, const char* aKeyBase,
693
+ const char* aType, nsACString& aResult)
694
+{
695
+ nsCAutoString hostKey;
696
+ hostKey.AppendASCII(aKeyBase);
697
+ hostKey.AppendLiteral("host");
698
+ nsCAutoString host;
699
+ nsresult rv = aGConf->GetString(hostKey, host);
700
+ if (NS_FAILED(rv))
701
+ return rv;
702
+ if (host.IsEmpty())
703
+ return NS_ERROR_FAILURE;
704
+
705
+ nsCAutoString portKey;
706
+ portKey.AppendASCII(aKeyBase);
707
+ portKey.AppendLiteral("port");
708
+ PRInt32 port;
709
+ rv = aGConf->GetInt(portKey, &port);
710
+ if (NS_FAILED(rv))
711
+ return rv;
712
+
713
+ SetProxyResult(aType, host, port, aResult);
714
+ return NS_OK;
715
+}
716
+
717
+/* copied from nsProtocolProxyService.cpp --- we should share this! */
718
+static void
719
+proxy_MaskIPv6Addr(PRIPv6Addr &addr, PRUint16 mask_len)
720
+{
721
+ if (mask_len == 128)
722
+ return;
723
+
724
+ if (mask_len > 96) {
725
+ addr.pr_s6_addr32[3] = PR_htonl(
726
+ PR_ntohl(addr.pr_s6_addr32[3]) & (~0L << (128 - mask_len)));
727
+ }
728
+ else if (mask_len > 64) {
729
+ addr.pr_s6_addr32[3] = 0;
730
+ addr.pr_s6_addr32[2] = PR_htonl(
731
+ PR_ntohl(addr.pr_s6_addr32[2]) & (~0L << (96 - mask_len)));
732
+ }
733
+ else if (mask_len > 32) {
734
+ addr.pr_s6_addr32[3] = 0;
735
+ addr.pr_s6_addr32[2] = 0;
736
+ addr.pr_s6_addr32[1] = PR_htonl(
737
+ PR_ntohl(addr.pr_s6_addr32[1]) & (~0L << (64 - mask_len)));
738
+ }
739
+ else {
740
+ addr.pr_s6_addr32[3] = 0;
741
+ addr.pr_s6_addr32[2] = 0;
742
+ addr.pr_s6_addr32[1] = 0;
743
+ addr.pr_s6_addr32[0] = PR_htonl(
744
+ PR_ntohl(addr.pr_s6_addr32[0]) & (~0L << (32 - mask_len)));
745
+ }
746
+}
747
+
748
+static PRBool ConvertToIPV6Addr(const nsACString& aName,
749
+ PRIPv6Addr* aAddr)
750
+{
751
+ PRNetAddr addr;
752
+ if (PR_StringToNetAddr(PromiseFlatCString(aName).get(), &addr) != PR_SUCCESS)
753
+ return PR_FALSE;
754
+
755
+ PRIPv6Addr ipv6;
756
+ // convert parsed address to IPv6
757
+ if (addr.raw.family == PR_AF_INET) {
758
+ // convert to IPv4-mapped address
759
+ PR_ConvertIPv4AddrToIPv6(addr.inet.ip, &ipv6);
760
+ } else if (addr.raw.family == PR_AF_INET6) {
761
+ // copy the address
762
+ memcpy(&ipv6, &addr.ipv6.ip, sizeof(PRIPv6Addr));
763
+ } else {
764
+ return PR_FALSE;
765
+ }
766
+
767
+ return PR_TRUE;
768
+}
769
+
770
+static PRBool GConfIgnoreHost(const nsACString& aIgnore,
771
+ const nsACString& aHost)
772
+{
773
+ if (aIgnore.Equals(aHost, nsCaseInsensitiveCStringComparator()))
774
+ return PR_TRUE;
775
+
776
+ if (StringBeginsWith(aIgnore, NS_LITERAL_CSTRING("*")) &&
777
+ StringEndsWith(aHost, nsDependentCSubstring(aIgnore, 1),
778
+ nsCaseInsensitiveCStringComparator()))
779
+ return PR_TRUE;
780
+
781
+ PRInt32 mask = 128;
782
+ nsReadingIterator<char> start;
783
+ nsReadingIterator<char> slash;
784
+ nsReadingIterator<char> end;
785
+ aIgnore.BeginReading(start);
786
+ aIgnore.BeginReading(slash);
787
+ aIgnore.EndReading(end);
788
+ if (FindCharInReadable('/', slash, end)) {
789
+ ++slash;
790
+ nsDependentCSubstring maskStr(slash, end);
791
+ nsCAutoString maskStr2(maskStr);
792
+ PRInt32 err;
793
+ mask = maskStr2.ToInteger(&err);
794
+ if (err != 0) {
795
+ mask = 128;
796
+ }
797
+ --slash;
798
+ } else {
799
+ slash = end;
800
+ }
801
+
802
+ PRIPv6Addr ignoreAddr, hostAddr;
803
+ if (!ConvertToIPV6Addr(aIgnore, &ignoreAddr) ||
804
+ !ConvertToIPV6Addr(aHost, &hostAddr))
805
+ return PR_FALSE;
806
+
807
+ proxy_MaskIPv6Addr(ignoreAddr, mask);
808
+ proxy_MaskIPv6Addr(hostAddr, mask);
809
+
810
+ return memcmp(&ignoreAddr, &hostAddr, sizeof(PRIPv6Addr)) == 0;
811
+}
812
+
813
+static nsresult
814
+GetProxyForURIFromGConf(nsIGConfService* aGConf,
815
+ const nsACString& aScheme,
816
+ const nsACString& aHost,
817
+ PRInt32 aPort,
818
+ nsACString& aResult)
819
+{
820
+ if (!IsProxyMode(aGConf, "manual")) {
821
+ aResult.AppendLiteral("DIRECT");
822
+ return NS_OK;
823
+ }
824
+
825
+ nsCOMPtr<nsIUTF8StringEnumerator> ignoreList;
826
+ if (NS_SUCCEEDED(aGConf->GetStringList(NS_LITERAL_CSTRING("/system/http_proxy/ignore_hosts"),
827
+ getter_AddRefs(ignoreList))) && ignoreList) {
828
+ while (PR_TRUE) {
829
+ PRBool hasMore;
830
+ if (NS_FAILED(ignoreList->HasMore(&hasMore)) || !hasMore)
831
+ break;
832
+ nsCAutoString s;
833
+ if (NS_SUCCEEDED(ignoreList->GetNext(s))) {
834
+ if (GConfIgnoreHost(s, aHost)) {
835
+ aResult.AppendLiteral("DIRECT");
836
+ return NS_OK;
837
+ }
838
+ }
839
+ }
840
+ }
841
+
842
+ nsresult rv = SetProxyResultFromGConf(aGConf, "/system/proxy/socks_", "SOCKS", aResult);
843
+ if (NS_SUCCEEDED(rv))
844
+ return rv;
845
+
846
+ if (aScheme.LowerCaseEqualsLiteral("http")) {
847
+ rv = SetProxyResultFromGConf(aGConf, "/system/http_proxy/", "PROXY", aResult);
848
+ } else if (aScheme.LowerCaseEqualsLiteral("https")) {
849
+ rv = SetProxyResultFromGConf(aGConf, "/system/proxy/secure_", "PROXY", aResult);
850
+ } else if (aScheme.LowerCaseEqualsLiteral("ftp")) {
851
+ rv = SetProxyResultFromGConf(aGConf, "/system/proxy/ftp_", "PROXY", aResult);
852
+ } else {
853
+ rv = NS_ERROR_FAILURE;
854
+ }
855
+
856
+ if (NS_FAILED(rv)) {
857
+ aResult.AppendLiteral("DIRECT");
858
+ }
859
+ return NS_OK;
860
+}
861
+
862
+nsresult
863
+nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult)
864
+{
865
+ nsCAutoString scheme;
866
+ nsresult rv = aURI->GetScheme(scheme);
867
+ if (NS_FAILED(rv))
868
+ return rv;
869
+
870
+ nsCAutoString host;
871
+ rv = aURI->GetHost(host);
872
+ if (NS_FAILED(rv))
873
+ return rv;
874
+
875
+ PRInt32 port;
876
+ rv = aURI->GetPort(&port);
877
+ if (NS_FAILED(rv))
878
+ return rv;
879
+
880
+ if (!mGConf)
881
+ return GetProxyForURIFromEnvironment(scheme, host, port, aResult);
882
+
883
+ return GetProxyForURIFromGConf(mGConf, scheme, host, port, aResult);
884
+}
885
+
886
+#define NS_UNIXSYSTEMPROXYSERVICE_CID /* 0fa3158c-d5a7-43de-9181-a285e74cf1d4 */\
887
+ { 0x0fa3158c, 0xd5a7, 0x43de, \
888
+ {0x91, 0x81, 0xa2, 0x85, 0xe7, 0x4c, 0xf1, 0xd4 } }
889
+
890
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUnixSystemProxySettings, Init)
891
+
892
+static const nsModuleComponentInfo components[] = {
893
+ { "Unix System Proxy Settings Service",
894
+ NS_UNIXSYSTEMPROXYSERVICE_CID,
895
+ NS_SYSTEMPROXYSETTINGS_CONTRACTID,
896
+ nsUnixSystemProxySettingsConstructor }
897
+};
898
+
899
+NS_IMPL_NSGETMODULE(unixproxy, components)
900