mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 03:54:33 +02:00
8212926: HttpClient does not retrieve files with large sizes over HTTP/1.1
Reviewed-by: chegar, dfuchs
This commit is contained in:
parent
0d815c2677
commit
ae21c81dd7
3 changed files with 192 additions and 16 deletions
|
@ -236,20 +236,20 @@ class Http1Response<T> {
|
|||
* Return known fixed content length or -1 if chunked, or -2 if no content-length
|
||||
* information in which case, connection termination delimits the response body
|
||||
*/
|
||||
int fixupContentLen(int clen) {
|
||||
long fixupContentLen(long clen) {
|
||||
if (request.method().equalsIgnoreCase("HEAD") || responseCode == HTTP_NOT_MODIFIED) {
|
||||
return 0;
|
||||
return 0L;
|
||||
}
|
||||
if (clen == -1) {
|
||||
if (clen == -1L) {
|
||||
if (headers.firstValue("Transfer-encoding").orElse("")
|
||||
.equalsIgnoreCase("chunked")) {
|
||||
return -1;
|
||||
return -1L;
|
||||
}
|
||||
if (responseCode == 101) {
|
||||
// this is a h2c or websocket upgrade, contentlength must be zero
|
||||
return 0;
|
||||
return 0L;
|
||||
}
|
||||
return -2;
|
||||
return -2L;
|
||||
}
|
||||
return clen;
|
||||
}
|
||||
|
@ -383,9 +383,8 @@ class Http1Response<T> {
|
|||
|
||||
final CompletableFuture<U> cf = new MinimalFuture<>();
|
||||
|
||||
int clen0 = (int)headers.firstValueAsLong("Content-Length").orElse(-1);
|
||||
|
||||
final int clen = fixupContentLen(clen0);
|
||||
long clen0 = headers.firstValueAsLong("Content-Length").orElse(-1L);
|
||||
final long clen = fixupContentLen(clen0);
|
||||
|
||||
// expect-continue reads headers and body twice.
|
||||
// if we reach here, we must reset the headersReader state.
|
||||
|
|
|
@ -46,7 +46,7 @@ import static java.lang.String.format;
|
|||
class ResponseContent {
|
||||
|
||||
final HttpResponse.BodySubscriber<?> pusher;
|
||||
final int contentLength;
|
||||
final long contentLength;
|
||||
final HttpHeaders headers;
|
||||
// this needs to run before we complete the body
|
||||
// so that connection can be returned to pool
|
||||
|
@ -54,7 +54,7 @@ class ResponseContent {
|
|||
private final String dbgTag;
|
||||
|
||||
ResponseContent(HttpConnection connection,
|
||||
int contentLength,
|
||||
long contentLength,
|
||||
HttpHeaders h,
|
||||
HttpResponse.BodySubscriber<?> userSubscriber,
|
||||
Runnable onFinished)
|
||||
|
@ -474,14 +474,14 @@ class ResponseContent {
|
|||
}
|
||||
|
||||
class FixedLengthBodyParser implements BodyParser {
|
||||
final int contentLength;
|
||||
final long contentLength;
|
||||
final Consumer<Throwable> onComplete;
|
||||
final Logger debug = Utils.getDebugLogger(this::dbgString, Utils.DEBUG);
|
||||
final String dbgTag = ResponseContent.this.dbgTag + "/FixedLengthBodyParser";
|
||||
volatile int remaining;
|
||||
volatile long remaining;
|
||||
volatile Throwable closedExceptionally;
|
||||
volatile AbstractSubscription sub;
|
||||
FixedLengthBodyParser(int contentLength, Consumer<Throwable> onComplete) {
|
||||
FixedLengthBodyParser(long contentLength, Consumer<Throwable> onComplete) {
|
||||
this.contentLength = this.remaining = contentLength;
|
||||
this.onComplete = onComplete;
|
||||
}
|
||||
|
@ -527,7 +527,7 @@ class ResponseContent {
|
|||
}
|
||||
boolean completed = false;
|
||||
try {
|
||||
int unfulfilled = remaining;
|
||||
long unfulfilled = remaining;
|
||||
if (debug.on())
|
||||
debug.log("Parser got %d bytes (%d remaining / %d)",
|
||||
b.remaining(), unfulfilled, contentLength);
|
||||
|
@ -541,7 +541,7 @@ class ResponseContent {
|
|||
// demand.
|
||||
boolean hasDemand = sub.demand().tryDecrement();
|
||||
assert hasDemand;
|
||||
int amount = Math.min(b.remaining(), unfulfilled);
|
||||
int amount = (int)Math.min(b.remaining(), unfulfilled); // safe cast
|
||||
unfulfilled = remaining -= amount;
|
||||
ByteBuffer buffer = Utils.sliceWithLimitedCapacity(b, amount);
|
||||
pusher.onNext(List.of(buffer.asReadOnlyBuffer()));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue