@@ -137,7 +137,7 @@ public class HttpWebConnection implements WebConnection {
137137 private static final String HACKED_COOKIE_POLICY = "mine" ;
138138
139139 // have one per thread because this is (re)configured for every call (see configureHttpProcessorBuilder)
140- // do not use a ThreadLocal because this in only accessed form this class
140+ // do not use a ThreadLocal because this in only accessed form this class, but we still need it synchronized
141141 private final Map <Thread , HttpClientBuilder > httpClientBuilder_ = new WeakHashMap <>();
142142 private final WebClient webClient_ ;
143143
@@ -211,7 +211,9 @@ public WebResponse getResponse(final WebRequest webRequest) throws IOException {
211211 // Calling code may catch the StackOverflowError, but due to the leak, the httpClient_ may
212212 // come out of connections and throw a ConnectionPoolTimeoutException.
213213 // => best solution, discard the HttpClient instance.
214- httpClientBuilder_ .remove (Thread .currentThread ());
214+ synchronized (httpClientBuilder_ ) {
215+ httpClientBuilder_ .remove (Thread .currentThread ());
216+ }
215217 throw e ;
216218 }
217219 }
@@ -531,24 +533,27 @@ private static HttpRequestBase buildHttpMethod(final HttpMethod submitMethod, fi
531533 * @return the initialized HTTP client
532534 */
533535 protected HttpClientBuilder getHttpClientBuilder () {
534- final Thread currentThread = Thread .currentThread ();
535- HttpClientBuilder builder = httpClientBuilder_ .get (currentThread );
536- if (builder == null ) {
537- builder = createHttpClientBuilder ();
538-
539- // this factory is required later
540- // to be sure this is done, we do it outside the createHttpClient() call
541- final RegistryBuilder <CookieSpecProvider > registeryBuilder
542- = RegistryBuilder .<CookieSpecProvider >create ()
543- .register (HACKED_COOKIE_POLICY , htmlUnitCookieSpecProvider_ );
544- builder .setDefaultCookieSpecRegistry (registeryBuilder .build ());
545-
546- builder .setDefaultCookieStore (new HtmlUnitCookieStore (webClient_ .getCookieManager ()));
547- builder .setUserAgent (webClient_ .getBrowserVersion ().getUserAgent ());
548- httpClientBuilder_ .put (currentThread , builder );
536+ synchronized (httpClientBuilder_ )
537+ {
538+ final Thread currentThread = Thread .currentThread ();
539+ HttpClientBuilder builder = httpClientBuilder_ .get (currentThread );
540+ if (builder == null ) {
541+ builder = createHttpClientBuilder ();
542+
543+ // this factory is required later
544+ // to be sure this is done, we do it outside the createHttpClient() call
545+ final RegistryBuilder <CookieSpecProvider > registeryBuilder
546+ = RegistryBuilder .<CookieSpecProvider >create ()
547+ .register (HACKED_COOKIE_POLICY , htmlUnitCookieSpecProvider_ );
548+ builder .setDefaultCookieSpecRegistry (registeryBuilder .build ());
549+
550+ builder .setDefaultCookieStore (new HtmlUnitCookieStore (webClient_ .getCookieManager ()));
551+ builder .setUserAgent (webClient_ .getBrowserVersion ().getUserAgent ());
552+ httpClientBuilder_ .put (currentThread , builder );
553+ }
554+
555+ return builder ;
549556 }
550-
551- return builder ;
552557 }
553558
554559 /**
@@ -1288,7 +1293,9 @@ public synchronized String toString() {
12881293 */
12891294 @ Override
12901295 public void close () {
1291- httpClientBuilder_ .clear ();
1296+ synchronized (httpClientBuilder_ ) {
1297+ httpClientBuilder_ .clear ();
1298+ }
12921299 sharedAuthCache_ .clear ();
12931300 httpClientContextByThread_ .clear ();
12941301
0 commit comments