EVALUATION
changeset:
http://hg.openjdk.java.net/jdk7/tl/jdk/rev/69002275e0e2
|
|
|
EVALUATION
Yes, this is a bug. The suggested fix would work, except that it would remove all requests belonging to the current thread. Normally, there is only one request at a time per-thread, but because we provide a number of callback APIs (eg. Authenticator and ResponseCache), it is possible for multiple HTTP requests to occur re-entrantly. The plugin does actually use this capability (with the ResponseCache).
We have another fix which also works, but by exposing the key used in the authentication cache outside of AuthenticationInfo, this allows all requests to be terminated correctly, inlcuding ones, that have no username/password returned.
|
|
|
SUGGESTED FIX
This fix was produced and tested against a 1.6.0_10 workspace but should be obviously applicable to earlier releases. The affected files are in the sun.net.www.protocol.http package.
------- AuthenticationInfo.java -------
*** //C/Users/kbr/forte4j/platform/intel-win/bin/util/tmp/sccs.000292 Mon Jan 7 20:36:51 2008
--- AuthenticationInfo.java Mon Jan 7 20:34:34 2008
***************
*** 9,16 ****
--- 9,19 ----
import java.io.*;
import java.net.*;
+ import java.util.ArrayList;
import java.util.Hashtable;
+ import java.util.Iterator;
import java.util.LinkedList;
+ import java.util.List;
import java.util.ListIterator;
import java.util.Enumeration;
import java.util.HashMap;
***************
*** 125,134 ****
/* signal completion of an authentication (whether it succeeded or not)
* so that other threads can continue.
*/
! static private void requestCompleted (String key) {
synchronized (requests) {
! boolean waspresent = requests.remove (key) != null;
! assert waspresent;
requests.notifyAll();
}
}
--- 128,147 ----
/* signal completion of an authentication (whether it succeeded or not)
* so that other threads can continue.
*/
! static private void requestCompleted () {
synchronized (requests) {
! // Remove any outstanding requests owned by the current thread
! List/*<String>*/ keys = new ArrayList();
! Thread current = Thread.currentThread();
! for (Iterator iter = requests.keySet().iterator(); iter.hasNext(); ) {
! String key = (String) iter.next();
! if (requests.get(key) == current) {
! keys.add(key);
! }
! }
! for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
! requests.remove(iter.next());
! }
requests.notifyAll();
}
}
***************
*** 314,325 ****
endAuthRequest();
}
! void endAuthRequest () {
if (!serializeAuth) {
return;
}
synchronized (requests) {
! requestCompleted (cacheKey(true));
}
}
--- 327,338 ----
endAuthRequest();
}
! static void endAuthRequest () {
if (!serializeAuth) {
return;
}
synchronized (requests) {
! requestCompleted ();
}
}
------- HttpURLConnection.java -------
*** //C/Users/kbr/forte4j/platform/intel-win/bin/util/tmp/sccs.000292 Mon Jan 7 20:36:51 2008
--- HttpURLConnection.java Mon Jan 7 20:22:43 2008
***************
*** 1266,1277 ****
}
throw e;
} finally {
! if (respCode == HTTP_PROXY_AUTH && proxyAuthentication != null) {
! proxyAuthentication.endAuthRequest();
! }
! else if (respCode == HTTP_UNAUTHORIZED && serverAuthentication != null) {
! serverAuthentication.endAuthRequest();
! }
}
}
--- 1266,1273 ----
}
throw e;
} finally {
! // Notify other threads that our authentication requests are complete
! AuthenticationInfo.endAuthRequest();
}
}
***************
*** 1425,1433 ****
statusLine + "\"");
}
} finally {
! if (respCode == HTTP_PROXY_AUTH && proxyAuthentication != null) {
! proxyAuthentication.endAuthRequest();
! }
}
// restore original request headers
--- 1421,1427 ----
statusLine + "\"");
}
} finally {
! AuthenticationInfo.endAuthRequest();
}
// restore original request headers
|
|
|
|