diff --git a/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java b/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
index f107e18..eca10e5 100644
|
a
|
b
|
|
| 3 | 3 | |
| 4 | 4 | import java.io.FileNotFoundException; |
| 5 | 5 | import java.io.IOException; |
| 6 | | import java.net.HttpURLConnection; |
| 7 | 6 | import java.net.URL; |
| 8 | | import java.net.URLConnection; |
| 9 | 7 | import java.util.HashSet; |
| 10 | 8 | import java.util.List; |
| 11 | 9 | import java.util.Map; |
| 12 | | import java.util.Map.Entry; |
| 13 | 10 | import java.util.Random; |
| 14 | 11 | import java.util.Set; |
| 15 | 12 | import java.util.concurrent.ConcurrentHashMap; |
| … |
… |
|
| 26 | 23 | import org.openstreetmap.josm.Main; |
| 27 | 24 | import org.openstreetmap.josm.data.cache.ICachedLoaderListener.LoadResult; |
| 28 | 25 | import org.openstreetmap.josm.data.preferences.IntegerProperty; |
| | 26 | import org.openstreetmap.josm.tools.HttpClient; |
| 29 | 27 | import org.openstreetmap.josm.tools.Utils; |
| 30 | 28 | |
| 31 | 29 | /** |
| … |
… |
private boolean loadObject() {
|
| 310 | 308 | return true; |
| 311 | 309 | } |
| 312 | 310 | |
| 313 | | HttpURLConnection urlConn = getURLConnection(getUrl(), true); |
| | 311 | // TODO use #getURLConnection() instead? |
| | 312 | final HttpClient request = HttpClient.create(getUrl()).useCache(false); |
| 314 | 313 | |
| 315 | 314 | if (isObjectLoadable() && |
| 316 | 315 | (now - attributes.getLastModification()) <= ABSOLUTE_EXPIRE_TIME_LIMIT) { |
| 317 | | urlConn.setIfModifiedSince(attributes.getLastModification()); |
| | 316 | request.setIfModifiedSince(attributes.getLastModification()); |
| 318 | 317 | } |
| 319 | 318 | if (isObjectLoadable() && attributes.getEtag() != null) { |
| 320 | | urlConn.addRequestProperty("If-None-Match", attributes.getEtag()); |
| | 319 | request.setHeader("If-None-Match", attributes.getEtag()); |
| 321 | 320 | } |
| 322 | 321 | |
| 323 | | log.log(Level.INFO, "GET {0} -> {1}", new Object[]{getUrl(), urlConn.getResponseCode()}); |
| | 322 | final HttpClient.Response urlConn = request.connect(); |
| 324 | 323 | |
| 325 | | // follow redirects |
| 326 | | for (int i = 0; i < 5; i++) { |
| 327 | | if (urlConn.getResponseCode() == 302) { |
| 328 | | urlConn = getURLConnection(new URL(urlConn.getHeaderField("Location")), true); |
| 329 | | } else { |
| 330 | | break; |
| 331 | | } |
| 332 | | } |
| 333 | | if (urlConn.getResponseCode() == 304) { |
| | 324 | if (urlConn.getResponseCode() == 302) { |
| 334 | 325 | // If isModifiedSince or If-None-Match has been set |
| 335 | 326 | // and the server answers with a HTTP 304 = "Not Modified" |
| 336 | 327 | log.log(Level.FINE, "JCS - IfModifiedSince/Etag test: local version is up to date: {0}", getUrl()); |
| 337 | 328 | return true; |
| 338 | | } else if (isObjectLoadable() // we have an object in cache, but we haven't received 304 resposne code |
| | 329 | } else if (isObjectLoadable() // we have an object in cache, but we haven't received 304 response code |
| 339 | 330 | && ( |
| 340 | | (attributes.getEtag() != null && attributes.getEtag().equals(urlConn.getRequestProperty("ETag"))) || |
| | 331 | (attributes.getEtag() != null && attributes.getEtag().equals(urlConn.getHeaderField("ETag"))) || |
| 341 | 332 | attributes.getLastModification() == urlConn.getLastModified()) |
| 342 | 333 | ) { |
| 343 | 334 | // we sent ETag or If-Modified-Since, but didn't get 304 response code |
| 344 | 335 | // for further requests - use HEAD |
| 345 | 336 | String serverKey = getServerKey(); |
| 346 | | log.log(Level.INFO, "JCS - Host: {0} found not to return 304 codes for If-Modifed-Since or If-None-Match headers", |
| | 337 | log.log(Level.INFO, "JCS - Host: {0} found not to return 304 codes for If-Modified-Since or If-None-Match headers", |
| 347 | 338 | serverKey); |
| 348 | 339 | useHead.put(serverKey, Boolean.TRUE); |
| 349 | 340 | } |
| … |
… |
private boolean loadObject() {
|
| 360 | 351 | attributes.setResponseCode(urlConn.getResponseCode()); |
| 361 | 352 | byte[] raw; |
| 362 | 353 | if (urlConn.getResponseCode() == 200) { |
| 363 | | raw = Utils.readBytesFromStream(urlConn.getInputStream()); |
| | 354 | raw = Utils.readBytesFromStream(urlConn.getContent()); |
| 364 | 355 | } else { |
| 365 | 356 | raw = new byte[]{}; |
| 366 | 357 | } |
| … |
… |
protected boolean isResponseLoadable(Map<String, List<String>> headerFields, int
|
| 433 | 424 | |
| 434 | 425 | protected abstract V createCacheEntry(byte[] content); |
| 435 | 426 | |
| 436 | | protected CacheEntryAttributes parseHeaders(URLConnection urlConn) { |
| | 427 | protected CacheEntryAttributes parseHeaders(HttpClient.Response urlConn) { |
| 437 | 428 | CacheEntryAttributes ret = new CacheEntryAttributes(); |
| 438 | 429 | |
| 439 | 430 | Long lng = urlConn.getExpiration(); |
| … |
… |
protected CacheEntryAttributes parseHeaders(URLConnection urlConn) {
|
| 460 | 451 | ret.setLastModification(now); |
| 461 | 452 | ret.setEtag(urlConn.getHeaderField("ETag")); |
| 462 | 453 | |
| 463 | | if (Main.isDebugEnabled()) { |
| 464 | | for (Entry<String, List<String>> header: urlConn.getHeaderFields().entrySet()) { |
| 465 | | log.log(Level.FINE, "Response header - {0}: {1}", new Object[]{header.getKey(), header.getValue()}); |
| 466 | | } |
| 467 | | } |
| 468 | | |
| 469 | 454 | return ret; |
| 470 | 455 | } |
| 471 | 456 | |
| 472 | | private HttpURLConnection getURLConnection(URL url, boolean noCache) throws IOException { |
| 473 | | HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); |
| 474 | | urlConn.setRequestProperty("Accept", "text/html, image/png, image/jpeg, image/gif, */*"); |
| | 457 | private HttpClient getURLConnection(URL url, boolean noCache, String requestMethod) throws IOException { |
| | 458 | final HttpClient urlConn = HttpClient.create(url, requestMethod); |
| | 459 | urlConn.setAccept("text/html, image/png, image/jpeg, image/gif, */*"); |
| 475 | 460 | urlConn.setReadTimeout(readTimeout); // 30 seconds read timeout |
| 476 | 461 | urlConn.setConnectTimeout(connectTimeout); |
| 477 | 462 | if (headers != null) { |
| 478 | | for (Map.Entry<String, String> e: headers.entrySet()) { |
| 479 | | urlConn.setRequestProperty(e.getKey(), e.getValue()); |
| 480 | | } |
| | 463 | urlConn.setHeaders(headers); |
| 481 | 464 | } |
| 482 | 465 | |
| 483 | 466 | if (force || noCache) { |
| 484 | | urlConn.setUseCaches(false); |
| | 467 | urlConn.useCache(false); |
| 485 | 468 | } |
| 486 | 469 | return urlConn; |
| 487 | 470 | } |
| 488 | 471 | |
| 489 | 472 | private boolean isCacheValidUsingHead() throws IOException { |
| 490 | | HttpURLConnection urlConn = getURLConnection(getUrl(), false); |
| 491 | | urlConn.setRequestMethod("HEAD"); |
| 492 | | for (int i = 0; i < 5; i++) { |
| 493 | | if (urlConn.getResponseCode() == 302) { |
| 494 | | urlConn = getURLConnection(new URL(urlConn.getHeaderField("Location")), false); |
| 495 | | } else { |
| 496 | | break; |
| 497 | | } |
| 498 | | } |
| | 473 | final HttpClient.Response urlConn = getURLConnection(getUrl(), false, "HEAD").connect(); |
| 499 | 474 | long lastModified = urlConn.getLastModified(); |
| 500 | | return (attributes.getEtag() != null && attributes.getEtag().equals(urlConn.getRequestProperty("ETag"))) || |
| | 475 | return (attributes.getEtag() != null && attributes.getEtag().equals(urlConn.getHeaderField("ETag"))) || |
| 501 | 476 | (lastModified != 0 && lastModified <= attributes.getLastModification()); |
| 502 | 477 | } |
| 503 | 478 | |
diff --git a/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java b/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
index 64c933c..631b5ef 100644
|
a
|
b
|
|
| 6 | 6 | import java.io.ByteArrayInputStream; |
| 7 | 7 | import java.io.IOException; |
| 8 | 8 | import java.net.URL; |
| 9 | | import java.net.URLConnection; |
| 10 | 9 | import java.util.HashSet; |
| 11 | 10 | import java.util.List; |
| 12 | 11 | import java.util.Map; |
| … |
… |
|
| 30 | 29 | import org.openstreetmap.josm.data.cache.CacheEntryAttributes; |
| 31 | 30 | import org.openstreetmap.josm.data.cache.ICachedLoaderListener; |
| 32 | 31 | import org.openstreetmap.josm.data.cache.JCSCachedTileLoaderJob; |
| | 32 | import org.openstreetmap.josm.tools.HttpClient; |
| 33 | 33 | |
| 34 | 34 | /** |
| 35 | 35 | * @author Wiktor Niesiobędzki |
| … |
… |
public void submit() {
|
| 239 | 239 | } |
| 240 | 240 | |
| 241 | 241 | @Override |
| 242 | | protected CacheEntryAttributes parseHeaders(URLConnection urlConn) { |
| | 242 | protected CacheEntryAttributes parseHeaders(HttpClient.Response urlConn) { |
| 243 | 243 | CacheEntryAttributes ret = super.parseHeaders(urlConn); |
| 244 | 244 | // keep the expiration time between MINIMUM_EXPIRES and MAXIMUM_EXPIRES, so we will cache the tiles |
| 245 | 245 | // at least for some short period of time, but not too long |
diff --git a/src/org/openstreetmap/josm/tools/HttpClient.java b/src/org/openstreetmap/josm/tools/HttpClient.java
index 300c2b8..31ea2ba 100644
|
a
|
b
|
public String getResponseMessage() {
|
| 309 | 309 | /** |
| 310 | 310 | * Returns the {@code Content-Encoding} header. |
| 311 | 311 | * @return {@code Content-Encoding} HTTP header |
| | 312 | * @see HttpURLConnection#getContentEncoding() |
| 312 | 313 | */ |
| 313 | 314 | public String getContentEncoding() { |
| 314 | 315 | return connection.getContentEncoding(); |
| … |
… |
public String getContentType() {
|
| 323 | 324 | } |
| 324 | 325 | |
| 325 | 326 | /** |
| | 327 | * Returns the {@code Expire} header. |
| | 328 | * @return {@code Expire} HTTP header |
| | 329 | * @see HttpURLConnection#getExpiration() |
| | 330 | */ |
| | 331 | public long getExpiration() { |
| | 332 | return connection.getExpiration(); |
| | 333 | } |
| | 334 | |
| | 335 | /** |
| | 336 | * Returns the {@code Last-Modified} header. |
| | 337 | * @return {@code Last-Modified} HTTP header |
| | 338 | * @see HttpURLConnection#getLastModified() |
| | 339 | */ |
| | 340 | public long getLastModified() { |
| | 341 | return connection.getLastModified(); |
| | 342 | } |
| | 343 | |
| | 344 | /** |
| 326 | 345 | * Returns the {@code Content-Length} header. |
| 327 | 346 | * @return {@code Content-Length} HTTP header |
| | 347 | * @see HttpURLConnection#getContentLengthLong() |
| 328 | 348 | */ |
| 329 | 349 | public long getContentLength() { |
| 330 | 350 | return connection.getContentLengthLong(); |
| … |
… |
public String getHeaderField(String name) {
|
| 353 | 373 | } |
| 354 | 374 | |
| 355 | 375 | /** |
| | 376 | * Returns an unmodifiable Map mapping header keys to a List of header values. |
| | 377 | * @return unmodifiable Map mapping header keys to a List of header values |
| | 378 | * @see HttpURLConnection#getHeaderFields() |
| | 379 | */ |
| | 380 | public Map<String, List<String>> getHeaderFields() { |
| | 381 | return connection.getHeaderFields(); |
| | 382 | } |
| | 383 | |
| | 384 | /** |
| 356 | 385 | * @see HttpURLConnection#disconnect() |
| 357 | 386 | */ |
| 358 | 387 | public void disconnect() { |