1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.core5.http.impl.io;
29
30 import org.apache.hc.core5.annotation.Contract;
31 import org.apache.hc.core5.annotation.ThreadingBehavior;
32 import org.apache.hc.core5.http.ClassicHttpRequest;
33 import org.apache.hc.core5.http.io.HttpClientConnection;
34 import org.apache.hc.core5.http.io.ResponseOutOfOrderStrategy;
35 import org.apache.hc.core5.util.Args;
36 import org.apache.hc.core5.util.Timeout;
37
38 import java.io.IOException;
39 import java.io.InputStream;
40
41
42
43
44
45
46
47
48
49 @Contract(threading = ThreadingBehavior.IMMUTABLE)
50 public final class MonitoringResponseOutOfOrderStrategy implements ResponseOutOfOrderStrategy {
51
52 private static final int DEFAULT_CHUNK_SIZE = 8 * 1024;
53
54 public static final MonitoringResponseOutOfOrderStrategy INSTANCE = new MonitoringResponseOutOfOrderStrategy();
55
56 private final long chunkSize;
57 private final long maxChunksToCheck;
58
59
60
61
62 public MonitoringResponseOutOfOrderStrategy() {
63 this(DEFAULT_CHUNK_SIZE);
64 }
65
66
67
68
69
70
71 public MonitoringResponseOutOfOrderStrategy(final long chunkSize) {
72 this(chunkSize, Long.MAX_VALUE);
73 }
74
75
76
77
78
79
80
81
82 public MonitoringResponseOutOfOrderStrategy(final long chunkSize, final long maxChunksToCheck) {
83 this.chunkSize = Args.positive(chunkSize, "chunkSize");
84 this.maxChunksToCheck = Args.positive(maxChunksToCheck, "maxChunksToCheck");
85 }
86
87 @Override
88 public boolean isEarlyResponseDetected(
89 final ClassicHttpRequest request,
90 final HttpClientConnection connection,
91 final InputStream inputStream,
92 final long totalBytesSent,
93 final long nextWriteSize) throws IOException {
94 if (nextWriteStartsNewChunk(totalBytesSent, nextWriteSize)) {
95 final boolean ssl = connection.getSSLSession() != null;
96 return ssl ? connection.isDataAvailable(Timeout.ONE_MILLISECOND) : (inputStream.available() > 0);
97 }
98 return false;
99 }
100
101 private boolean nextWriteStartsNewChunk(final long totalBytesSent, final long nextWriteSize) {
102 final long currentChunkIndex = Math.min(totalBytesSent / chunkSize, maxChunksToCheck);
103 final long newChunkIndex = Math.min((totalBytesSent + nextWriteSize) / chunkSize, maxChunksToCheck);
104 return currentChunkIndex < newChunkIndex;
105 }
106
107 @Override
108 public String toString() {
109 return "DefaultResponseOutOfOrderStrategy{chunkSize=" + chunkSize + ", maxChunksToCheck=" + maxChunksToCheck + '}';
110 }
111 }