Skip to content

Commit 76c76c2

Browse files
authored
mcopy: check for unsupported HEAD before failing request (#551)
1 parent 74d9ecc commit 76c76c2

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

src/main/java/me/itzg/helpers/http/FetchBuilderBase.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package me.itzg.helpers.http;
22

3-
import static io.netty.handler.codec.http.HttpHeaderNames.*;
3+
import static io.netty.handler.codec.http.HttpHeaderNames.ACCEPT;
4+
import static io.netty.handler.codec.http.HttpHeaderNames.AUTHORIZATION;
5+
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
46

5-
import com.fasterxml.jackson.databind.ObjectMapper;
6-
import io.netty.handler.codec.http.HttpHeaderNames;
7-
import io.netty.handler.codec.http.HttpHeaders;
8-
import io.netty.handler.codec.http.HttpStatusClass;
9-
import io.netty.handler.codec.http.HttpUtil;
107
import java.net.URI;
118
import java.net.URISyntaxException;
129
import java.nio.charset.StandardCharsets;
@@ -25,11 +22,19 @@
2522
import java.util.regex.Matcher;
2623
import java.util.regex.Pattern;
2724
import java.util.stream.Collectors;
25+
26+
import org.slf4j.Logger;
27+
28+
import com.fasterxml.jackson.databind.ObjectMapper;
29+
30+
import io.netty.handler.codec.http.HttpHeaderNames;
31+
import io.netty.handler.codec.http.HttpHeaders;
32+
import io.netty.handler.codec.http.HttpStatusClass;
33+
import io.netty.handler.codec.http.HttpUtil;
2834
import lombok.extern.slf4j.Slf4j;
2935
import me.itzg.helpers.errors.GenericException;
3036
import me.itzg.helpers.http.SharedFetch.Options;
3137
import me.itzg.helpers.json.ObjectMappers;
32-
import org.slf4j.Logger;
3338
import reactor.core.publisher.Mono;
3439
import reactor.netty.ByteBufMono;
3540
import reactor.netty.Connection;
@@ -246,12 +251,14 @@ protected boolean notExpectedContentType(HttpClientResponse resp) {
246251

247252
/**
248253
* CDN providers like bukkit don't support HEAD and respond with a 200 OK and redirect to a path like /error?aspxerrorpath=/projects/worldedit/files/latest
254+
* Also, S3 object storage services generally don't support HEAD and respond with 403 Forbidden when trying to fetch an object.
249255
* @param resp the response to evaluate
250256
* @return true if this response to a HEAD seems to indicate it is not supported
251257
*/
252258
protected static boolean isHeadUnsupportedResponse(HttpClientResponse resp) {
253-
return resp.path().equals("error") &&
254-
HttpUtil.getMimeType(resp.responseHeaders().get(HttpHeaderNames.CONTENT_TYPE.toString())).equals("text/html");
259+
return resp.status().code() == 403 ||
260+
(resp.path().equals("error") &&
261+
HttpUtil.getMimeType(resp.responseHeaders().get(HttpHeaderNames.CONTENT_TYPE.toString())).equals("text/html"));
255262
}
256263

257264
protected <R> Mono<R> failedContentTypeMono(HttpClientResponse resp) {

src/main/java/me/itzg/helpers/http/OutputToDirectoryFetchBuilder.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@
44
import static io.netty.handler.codec.http.HttpHeaderNames.LAST_MODIFIED;
55
import static java.util.Objects.requireNonNull;
66

7-
import io.netty.handler.codec.http.HttpHeaderNames;
8-
import io.netty.handler.codec.http.HttpResponseStatus;
97
import java.io.IOException;
108
import java.nio.file.Files;
119
import java.nio.file.Path;
1210
import java.time.Instant;
11+
12+
import org.jetbrains.annotations.NotNull;
13+
14+
import io.netty.handler.codec.http.HttpHeaderNames;
15+
import io.netty.handler.codec.http.HttpResponseStatus;
1316
import lombok.Setter;
1417
import lombok.experimental.Accessors;
1518
import lombok.extern.slf4j.Slf4j;
1619
import me.itzg.helpers.files.ReactiveFileUtils;
17-
import org.jetbrains.annotations.NotNull;
1820
import reactor.core.publisher.Mono;
1921
import reactor.core.scheduler.Schedulers;
2022
import reactor.netty.ByteBufFlux;
@@ -75,14 +77,14 @@ public Mono<Path> assemble() {
7577
.head()
7678
.uri(uri())
7779
.responseSingle((resp, bodyMono) -> {
78-
if (notSuccess(resp)) {
79-
return failedRequestMono(resp, bodyMono, "Extracting filename");
80-
}
81-
8280
if (isHeadUnsupportedResponse(resp)) {
8381
return assembleFileDownloadNameViaGet(client);
8482
}
8583

84+
if (notSuccess(resp)) {
85+
return failedRequestMono(resp, bodyMono, "Extracting filename");
86+
}
87+
8688
final Path outputFile = outputDirectory.resolve(extractFilename(resp));
8789
final Instant lastModified = respLastModified(resp);
8890

0 commit comments

Comments
 (0)