80 String authscheme = parser.findKey(0); |
80 String authscheme = parser.findKey(0); |
81 |
81 |
82 String realm = parser.findValue("realm"); |
82 String realm = parser.findValue("realm"); |
83 java.net.Authenticator.RequestorType rtype = proxy ? PROXY : SERVER; |
83 java.net.Authenticator.RequestorType rtype = proxy ? PROXY : SERVER; |
84 URL url = toURL(uri, req.method(), proxy); |
84 URL url = toURL(uri, req.method(), proxy); |
|
85 String host; |
|
86 int port; |
|
87 String protocol; |
|
88 InetSocketAddress proxyAddress; |
|
89 if (proxy && (proxyAddress = req.proxy()) != null) { |
|
90 // request sent to server through proxy |
|
91 proxyAddress = req.proxy(); |
|
92 host = proxyAddress.getHostString(); |
|
93 port = proxyAddress.getPort(); |
|
94 protocol = "http"; // we don't support https connection to proxy |
|
95 } else { |
|
96 // direct connection to server or proxy |
|
97 host = uri.getHost(); |
|
98 port = uri.getPort(); |
|
99 protocol = uri.getScheme(); |
|
100 } |
85 |
101 |
86 // needs to be instance method in Authenticator |
102 // needs to be instance method in Authenticator |
87 return auth.requestPasswordAuthenticationInstance(uri.getHost(), |
103 return auth.requestPasswordAuthenticationInstance(host, |
88 null, |
104 null, |
89 uri.getPort(), |
105 port, |
90 uri.getScheme(), |
106 protocol, |
91 realm, |
107 realm, |
92 authscheme, |
108 authscheme, |
93 url, |
109 url, |
94 rtype |
110 rtype |
95 ); |
111 ); |
233 AuthInfo au = exchange.serverauth; |
249 AuthInfo au = exchange.serverauth; |
234 cache.store(au.scheme, req.uri(), false, au.credentials); |
250 cache.store(au.scheme, req.uri(), false, au.credentials); |
235 } |
251 } |
236 if (exchange.proxyauth != null && !exchange.proxyauth.fromcache) { |
252 if (exchange.proxyauth != null && !exchange.proxyauth.fromcache) { |
237 AuthInfo au = exchange.proxyauth; |
253 AuthInfo au = exchange.proxyauth; |
238 cache.store(au.scheme, req.uri(), false, au.credentials); |
254 URI proxyURI = getProxyURI(req); |
|
255 if (proxyURI != null) { |
|
256 cache.store(au.scheme, proxyURI, true, au.credentials); |
|
257 } |
239 } |
258 } |
240 return null; |
259 return null; |
241 } |
260 } |
242 |
261 |
243 boolean proxy = status == PROXY_UNAUTHORIZED; |
262 boolean proxy = status == PROXY_UNAUTHORIZED; |
332 } |
351 } |
333 |
352 |
334 // Note: Make sure that Cache and CacheEntry do not keep any strong |
353 // Note: Make sure that Cache and CacheEntry do not keep any strong |
335 // reference to the HttpClient: it would prevent the client being |
354 // reference to the HttpClient: it would prevent the client being |
336 // GC'ed when no longer referenced. |
355 // GC'ed when no longer referenced. |
337 static class Cache { |
356 static final class Cache { |
338 final LinkedList<CacheEntry> entries = new LinkedList<>(); |
357 final LinkedList<CacheEntry> entries = new LinkedList<>(); |
|
358 |
|
359 Cache() {} |
339 |
360 |
340 synchronized CacheEntry get(URI uri, boolean proxy) { |
361 synchronized CacheEntry get(URI uri, boolean proxy) { |
341 for (CacheEntry entry : entries) { |
362 for (CacheEntry entry : entries) { |
342 if (entry.equalsKey(uri, proxy)) { |
363 if (entry.equalsKey(uri, proxy)) { |
343 return entry; |
364 return entry; |
365 remove(authscheme, domain, proxy); |
386 remove(authscheme, domain, proxy); |
366 entries.add(new CacheEntry(authscheme, domain, proxy, value)); |
387 entries.add(new CacheEntry(authscheme, domain, proxy, value)); |
367 } |
388 } |
368 } |
389 } |
369 |
390 |
370 static class CacheEntry { |
391 static URI normalize(URI uri, boolean isPrimaryKey) { |
|
392 String path = uri.getPath(); |
|
393 if (path == null || path.isEmpty()) { |
|
394 // make sure the URI has a path, ignore query and fragment |
|
395 try { |
|
396 return new URI(uri.getScheme(), uri.getAuthority(), "/", null, null); |
|
397 } catch (URISyntaxException e) { |
|
398 throw new InternalError(e); |
|
399 } |
|
400 } else if (isPrimaryKey || !"/".equals(path)) { |
|
401 // remove extraneous components and normalize path |
|
402 return uri.resolve("."); |
|
403 } else { |
|
404 // path == "/" and the URI is not used to store |
|
405 // the primary key in the cache: nothing to do. |
|
406 return uri; |
|
407 } |
|
408 } |
|
409 |
|
410 static final class CacheEntry { |
371 final String root; |
411 final String root; |
372 final String scheme; |
412 final String scheme; |
373 final boolean proxy; |
413 final boolean proxy; |
374 final PasswordAuthentication value; |
414 final PasswordAuthentication value; |
375 |
415 |
376 CacheEntry(String authscheme, |
416 CacheEntry(String authscheme, |
377 URI uri, |
417 URI uri, |
378 boolean proxy, |
418 boolean proxy, |
379 PasswordAuthentication value) { |
419 PasswordAuthentication value) { |
380 this.scheme = authscheme; |
420 this.scheme = authscheme; |
381 this.root = uri.resolve(".").toString(); // remove extraneous components |
421 this.root = normalize(uri, true).toString(); // remove extraneous components |
382 this.proxy = proxy; |
422 this.proxy = proxy; |
383 this.value = value; |
423 this.value = value; |
384 } |
424 } |
385 |
425 |
386 public PasswordAuthentication value() { |
426 public PasswordAuthentication value() { |