|
20 | 20 | import org.apache.hc.client5.http.async.methods.SimpleRequestProducer; |
21 | 21 | import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; |
22 | 22 | import org.apache.hc.client5.http.impl.async.HttpAsyncClients; |
23 | | -import org.apache.hc.core5.concurrent.FutureCallback; |
24 | 23 | import org.apache.hc.core5.http.ContentType; |
25 | 24 | import org.apache.hc.core5.http.HttpException; |
26 | 25 | import org.apache.hc.core5.http.HttpResponse; |
| 26 | +import org.apache.hc.core5.http.HttpStatus; |
27 | 27 | import org.jetbrains.annotations.NotNull; |
28 | 28 | import reactor.core.publisher.Mono; |
29 | 29 | import reactor.core.scheduler.Schedulers; |
@@ -216,69 +216,23 @@ else if (skipUpToDate) { |
216 | 216 |
|
217 | 217 | return alreadyUpToDateMono |
218 | 218 | .filter(alreadyUpToDate -> !alreadyUpToDate) |
219 | | - .flatMap(notUsed -> |
220 | | - |
221 | | - Mono.<Path>create(sink -> { |
222 | | - |
223 | | - final SimpleRequestBuilder reqBuilder = SimpleRequestBuilder.get(resourceUrl); |
224 | | - |
225 | | - hcHttpClient.execute( |
226 | | - SimpleRequestProducer.create(reqBuilder.build()), |
227 | | - new ResponseToFileConsumer(outputFile), |
228 | | - new FutureCallback<Path>() { |
229 | | - |
230 | | - @Override |
231 | | - public void completed(Path result) { |
232 | | - sink.success(result); |
233 | | - } |
234 | | - |
235 | | - @Override |
236 | | - public void failed(Exception ex) { |
237 | | - sink.error(ex); |
238 | | - } |
239 | | - |
240 | | - @Override |
241 | | - public void cancelled() { |
242 | | - sink.success(); |
243 | | - } |
244 | | - } |
| 219 | + .flatMap(notUsed -> { |
| 220 | + final SimpleRequestBuilder reqBuilder = SimpleRequestBuilder.get(resourceUrl); |
| 221 | + applyHeaders(reqBuilder); |
| 222 | + |
| 223 | + return |
| 224 | + fileLastModifiedMono |
| 225 | + .map(instant -> reqBuilder.setHeader("If-Modified-Since", httpDateTimeFormatter.format(instant))) |
| 226 | + .then( |
| 227 | + Mono.<Path>create(sink -> { |
| 228 | + hcHttpClient.execute( |
| 229 | + SimpleRequestProducer.create(reqBuilder.build()), |
| 230 | + new ResponseToFileConsumer(outputFile), |
| 231 | + new MonoSinkFutureCallbackAdapter<>(sink) |
| 232 | + ); |
| 233 | + }) |
245 | 234 | ); |
246 | | - }) |
247 | | - |
248 | | - /*client |
249 | | - .headers(this::applyHeaders) |
250 | | - .headersWhen(headers -> |
251 | | - skipUpToDate ? |
252 | | - fileLastModifiedMono |
253 | | - .map(outputLastModified -> headers.set( |
254 | | - IF_MODIFIED_SINCE, |
255 | | - httpDateTimeFormatter.format(outputLastModified) |
256 | | - )) |
257 | | - .defaultIfEmpty(headers) |
258 | | - : Mono.just(headers) |
259 | | - ) |
260 | | - .followRedirect(true) |
261 | | - .doOnRequest(debugLogRequest(log, "file fetch")) |
262 | | - .doOnRequest( |
263 | | - (httpClientRequest, connection) -> statusHandler.call(FileDownloadStatus.DOWNLOADING, uri(), outputFile)) |
264 | | - .get() |
265 | | - .uri(resourceUrl) |
266 | | - .response((resp, byteBufFlux) -> { |
267 | | - if (skipUpToDate && resp.status() == HttpResponseStatus.NOT_MODIFIED) { |
268 | | - log.debug("The file {} is already up to date", outputFile); |
269 | | - statusHandler.call(FileDownloadStatus.SKIP_FILE_UP_TO_DATE, uri(), outputFile); |
270 | | - return Mono.just(outputFile); |
271 | | - } |
272 | | -
|
273 | | - if (notSuccess(resp)) { |
274 | | - return failedRequestMono(resp, byteBufFlux.aggregate(), "Downloading file"); |
275 | | - } |
276 | | -
|
277 | | - return copyBodyInputStreamToFile(byteBufFlux, outputFile); |
278 | | - }) |
279 | | - .last() |
280 | | - .checkpoint("Fetching file into directory")*/ |
281 | | - ) |
| 235 | + }) |
282 | 236 | .defaultIfEmpty(outputFile); |
283 | 237 | } |
284 | 238 |
|
@@ -317,33 +271,43 @@ public ResponseToFileConsumer(Path outputFile) { |
317 | 271 |
|
318 | 272 | @Override |
319 | 273 | public void releaseResources() { |
320 | | - try { |
321 | | - channel.close(); |
322 | | - } catch (IOException e) { |
323 | | - throw new RuntimeException(e); |
| 274 | + if (channel != null) { |
| 275 | + try { |
| 276 | + channel.close(); |
| 277 | + } catch (IOException e) { |
| 278 | + throw new RuntimeException(e); |
| 279 | + } |
324 | 280 | } |
325 | 281 | } |
326 | 282 |
|
327 | 283 | @Override |
328 | 284 | protected int capacityIncrement() { |
329 | | - return 1024; |
| 285 | + return 4096; |
330 | 286 | } |
331 | 287 |
|
332 | 288 | @Override |
333 | 289 | protected void data(ByteBuffer src, boolean endOfStream) throws IOException { |
334 | | - amount += channel.write(src); |
335 | | - if (endOfStream) { |
336 | | - channel.close(); |
| 290 | + if (channel != null) { |
| 291 | + amount += channel.write(src); |
| 292 | + if (endOfStream) { |
| 293 | + channel.close(); |
337 | 294 |
|
338 | | - statusHandler.call(FileDownloadStatus.DOWNLOADED, uri(), outputFile); |
339 | | - downloadedHandler.call(uri(), outputFile, amount); |
| 295 | + statusHandler.call(FileDownloadStatus.DOWNLOADED, uri(), outputFile); |
| 296 | + downloadedHandler.call(uri(), outputFile, amount); |
| 297 | + } |
340 | 298 | } |
341 | 299 | } |
342 | 300 |
|
343 | 301 | @Override |
344 | 302 | protected void start(HttpResponse response, |
345 | 303 | ContentType contentType |
346 | 304 | ) throws HttpException, IOException { |
| 305 | + if (skipUpToDate && response.getCode() == HttpStatus.SC_NOT_MODIFIED) { |
| 306 | + log.debug("The file {} is already up to date", outputFile); |
| 307 | + statusHandler.call(FileDownloadStatus.SKIP_FILE_UP_TO_DATE, uri(), outputFile); |
| 308 | + return; |
| 309 | + } |
| 310 | + |
347 | 311 | statusHandler.call(FileDownloadStatus.DOWNLOADING, uri(), outputFile); |
348 | 312 |
|
349 | 313 | channel = Files.newByteChannel(outputFile, |
|
0 commit comments