|
5 | 5 | import static java.lang.System.currentTimeMillis; |
6 | 6 | import static java.util.Objects.requireNonNull; |
7 | 7 |
|
8 | | -import io.netty.handler.codec.http.HttpHeaders; |
9 | 8 | import io.netty.handler.codec.http.HttpResponseStatus; |
10 | 9 | import java.io.IOException; |
11 | 10 | import java.net.URI; |
|
18 | 17 | import me.itzg.helpers.errors.GenericException; |
19 | 18 | import me.itzg.helpers.files.ReactiveFileUtils; |
20 | 19 | import reactor.core.publisher.Mono; |
21 | | -import reactor.netty.ByteBufFlux; |
22 | | -import reactor.netty.http.client.HttpClientResponse; |
23 | 20 |
|
24 | 21 | @Slf4j |
25 | 22 | @Accessors(fluent = true) |
@@ -68,78 +65,69 @@ public Mono<Path> assemble() { |
68 | 65 | final boolean useIfModifiedSince = skipUpToDate && Files.exists(file); |
69 | 66 |
|
70 | 67 | return useReactiveClient(client -> |
71 | | - getConcurrencyLimiter().limit( |
72 | | - client |
73 | | - .doOnRequest((httpClientRequest, connection) -> |
74 | | - statusHandler.call(FileDownloadStatus.DOWNLOADING, uri, file) |
75 | | - ) |
76 | | - .headers(headers -> |
77 | | - setupHeaders(headers, useIfModifiedSince) |
78 | | - ) |
79 | | - .followRedirect(true) |
80 | | - .doOnRequest(debugLogRequest(log, "file fetch")) |
81 | | - .get() |
82 | | - .uri(uri) |
83 | | - .response((resp, byteBufFlux) -> |
84 | | - processResponse(resp, byteBufFlux, useIfModifiedSince, uri) |
85 | | - ) |
86 | | - .last() |
87 | | - .contextWrite(context -> context.put("downloadStart", currentTimeMillis())) |
88 | | - ) |
89 | | - ); |
90 | | - } |
91 | | - |
92 | | - private Mono<Path> processResponse(HttpClientResponse resp, ByteBufFlux byteBufFlux, boolean useIfModifiedSince, URI uri) { |
93 | | - final HttpResponseStatus status = resp.status(); |
94 | | - |
95 | | - if (useIfModifiedSince && status == NOT_MODIFIED) { |
96 | | - log.debug("The file {} is already up to date", file); |
97 | | - statusHandler.call(FileDownloadStatus.SKIP_FILE_UP_TO_DATE, uri, file); |
98 | | - return Mono.just(file); |
99 | | - } |
100 | | - |
101 | | - if (notSuccess(resp)) { |
102 | | - return failedRequestMono(resp, byteBufFlux.aggregate(), "Trying to retrieve file"); |
103 | | - } |
104 | | - |
105 | | - if (notExpectedContentType(resp)) { |
106 | | - return failedContentTypeMono(resp); |
107 | | - } |
108 | | - |
109 | | - return ReactiveFileUtils.copyByteBufFluxToFile(byteBufFlux, file) |
110 | | - .flatMap(fileSize -> { |
111 | | - statusHandler.call(FileDownloadStatus.DOWNLOADED, uri, file); |
112 | | - downloadedHandler.call(uri, file, fileSize); |
113 | | - return Mono |
114 | | - .deferContextual(contextView -> { |
115 | | - if (log.isDebugEnabled()) { |
116 | | - final long durationMillis = |
117 | | - currentTimeMillis() - contextView.<Long>get("downloadStart"); |
118 | | - log.debug("Download of {} took {} at {}", |
119 | | - uri, formatDuration(durationMillis), transferRate(durationMillis, fileSize) |
| 68 | + client |
| 69 | + .doOnRequest((httpClientRequest, connection) -> |
| 70 | + statusHandler.call(FileDownloadStatus.DOWNLOADING, uri, file) |
| 71 | + ) |
| 72 | + .headers(headers -> { |
| 73 | + if (useIfModifiedSince) { |
| 74 | + try { |
| 75 | + final FileTime lastModifiedTime; |
| 76 | + lastModifiedTime = Files.getLastModifiedTime(file); |
| 77 | + headers.set( |
| 78 | + IF_MODIFIED_SINCE, |
| 79 | + httpDateTimeFormatter.format(lastModifiedTime.toInstant()) |
120 | 80 | ); |
| 81 | + } catch (IOException e) { |
| 82 | + throw new GenericException("Unable to get last modified time of " + file, e); |
121 | 83 | } |
122 | | - return Mono.just(file); |
123 | | - }); |
124 | | - }); |
125 | | - } |
126 | 84 |
|
127 | | - private void setupHeaders(HttpHeaders headers, boolean useIfModifiedSince) { |
128 | | - if (useIfModifiedSince) { |
129 | | - try { |
130 | | - final FileTime lastModifiedTime; |
131 | | - lastModifiedTime = Files.getLastModifiedTime(file); |
132 | | - headers.set( |
133 | | - IF_MODIFIED_SINCE, |
134 | | - httpDateTimeFormatter.format(lastModifiedTime.toInstant()) |
135 | | - ); |
136 | | - } catch (IOException e) { |
137 | | - throw new GenericException("Unable to get last modified time of " + file, e); |
138 | | - } |
| 85 | + } |
139 | 86 |
|
140 | | - } |
| 87 | + applyHeaders(headers); |
| 88 | + }) |
| 89 | + .followRedirect(true) |
| 90 | + .doOnRequest(debugLogRequest(log, "file fetch")) |
| 91 | + .get() |
| 92 | + .uri(uri) |
| 93 | + .response((resp, byteBufFlux) -> { |
| 94 | + final HttpResponseStatus status = resp.status(); |
141 | 95 |
|
142 | | - applyHeaders(headers); |
| 96 | + if (useIfModifiedSince && status == NOT_MODIFIED) { |
| 97 | + log.debug("The file {} is already up to date", file); |
| 98 | + statusHandler.call(FileDownloadStatus.SKIP_FILE_UP_TO_DATE, uri, file); |
| 99 | + return Mono.just(file); |
| 100 | + } |
| 101 | + |
| 102 | + if (notSuccess(resp)) { |
| 103 | + return failedRequestMono(resp, byteBufFlux.aggregate(), "Trying to retrieve file"); |
| 104 | + } |
| 105 | + |
| 106 | + if (notExpectedContentType(resp)) { |
| 107 | + return failedContentTypeMono(resp); |
| 108 | + } |
| 109 | + |
| 110 | + return ReactiveFileUtils.copyByteBufFluxToFile(byteBufFlux, file) |
| 111 | + .flatMap(fileSize -> { |
| 112 | + statusHandler.call(FileDownloadStatus.DOWNLOADED, uri, file); |
| 113 | + downloadedHandler.call(uri, file, fileSize); |
| 114 | + return Mono |
| 115 | + .deferContextual(contextView -> { |
| 116 | + if (log.isDebugEnabled()) { |
| 117 | + final long durationMillis = |
| 118 | + currentTimeMillis() - contextView.<Long>get("downloadStart"); |
| 119 | + log.debug("Download of {} took {} at {}", |
| 120 | + uri, formatDuration(durationMillis), transferRate(durationMillis, fileSize) |
| 121 | + ); |
| 122 | + } |
| 123 | + return Mono.just(file); |
| 124 | + }); |
| 125 | + }); |
| 126 | + |
| 127 | + }) |
| 128 | + .last() |
| 129 | + .contextWrite(context -> context.put("downloadStart", currentTimeMillis())) |
| 130 | + ); |
143 | 131 | } |
144 | 132 |
|
145 | 133 | } |
0 commit comments