-
Notifications
You must be signed in to change notification settings - Fork 43
Expand file tree
/
Copy pathHttpStreamBase.java
More file actions
192 lines (167 loc) · 7.33 KB
/
HttpStreamBase.java
File metadata and controls
192 lines (167 loc) · 7.33 KB
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
package software.amazon.awssdk.crt.http;
import software.amazon.awssdk.crt.CRT;
import software.amazon.awssdk.crt.CrtResource;
import software.amazon.awssdk.crt.CrtRuntimeException;
import java.util.concurrent.CompletableFuture;
/**
* An base class represents a single Http Request/Response for both HTTP/1.1 and
* HTTP/2 and wraps the native resources from the aws-c-http library.
*
* Can be used to update the Window size, or to abort the stream early in the
* middle of sending/receiving Http Bodies.
*/
public class HttpStreamBase extends CrtResource {
/*
* Native code will call this constructor during
* HttpClientConnection.makeRequest()
*/
protected HttpStreamBase(long ptr) {
acquireNativeHandle(ptr);
}
/**
* Determines whether a resource releases its dependencies at the same time the
* native handle is released or if it waits.
* Resources that wait are responsible for calling releaseReferences() manually.
*/
@Override
protected boolean canReleaseReferencesImmediately() {
return true;
}
/**
* Cleans up the stream's associated native handle
*/
@Override
protected void releaseNativeHandle() {
if (!isNull()) {
httpStreamBaseRelease(getNativeHandle());
}
}
/*******************************************************************************
* Shared method
******************************************************************************/
/**
* Increment the flow-control window, so that response data continues downloading.
* <p>
* If {@link HttpClientConnectionManagerOptions#withManualWindowManagement} was set true,
* each HTTP stream has a flow-control window that shrinks as response
* body data is downloaded (headers do not affect the size of the window).
* {@link HttpClientConnectionManagerOptions#withWindowSize} sets the starting size for each HTTP stream's window.
* Whenever the window reaches zero, data stops downloading.
* Increment the window to keep data flowing.
* Maintain a larger window to keep up a high download throughput,
* parts cannot download in parallel unless the window is large enough to hold multiple parts.
* Maintain a smaller window to limit the amount of data buffered in memory.
* <p>
* If manual window management is disabled this call has no effect.
*
* @param windowSize How many bytes to increment the sliding window by.
* @see HttpClientConnectionManagerOptions#withManualWindowManagement
*/
public void incrementWindow(int windowSize) {
if (windowSize < 0) {
throw new IllegalArgumentException("windowSize must be >= 0. Actual value: " + windowSize);
}
if (!isNull()) {
httpStreamBaseIncrementWindow(getNativeHandle(), windowSize);
}
}
/**
* Activates the client stream.
*/
public void activate() {
if (!isNull()) {
httpStreamBaseActivate(getNativeHandle(), this);
}
}
/**
* Retrieves the Http Response Status Code
*
* @return The Http Response Status Code
*/
public int getResponseStatusCode() {
if (!isNull()) {
return httpStreamBaseGetResponseStatusCode(getNativeHandle());
}
throw new IllegalStateException("Can't get Status Code on Closed Stream");
}
/**
* Cancels the stream with the default error code (AWS_ERROR_HTTP_STREAM_CANCELLED).
* <p>
* For HTTP/1.1 streams, this is equivalent to closing the connection.
* For HTTP/2 streams, this sends a RST_STREAM frame with AWS_HTTP2_ERR_CANCEL.
* <p>
* The stream will complete with AWS_ERROR_HTTP_STREAM_CANCELLED, unless the stream is
* already completing for other reasons, or the stream is not activated,
* in which case this call will have no effect.
*/
public void cancel() {
if (!isNull()) {
httpStreamBaseCancelDefaultError(getNativeHandle());
}
}
/**
* Completion interface for writing data to an http stream.
*/
public interface HttpStreamWriteDataCompletionCallback {
void onWriteDataCompleted(int errorCode);
}
/**
* Write data to an HTTP stream. Works for both HTTP/1.1 and HTTP/2.
* The stream must have been created with {@code useManualDataWrites = true}.
* You must call activate() before using this function.
*
* @param data data to send, or null to write zero bytes. Pass null with
* endStream=true to signal end-of-body without sending additional data.
* @param endStream if true, this is the last data to be sent on this stream.
* @param completionCallback invoked when the data has been flushed or an error occurs.
*/
public void writeData(final byte[] data, boolean endStream,
final HttpStreamWriteDataCompletionCallback completionCallback) {
if (isNull()) {
throw new IllegalStateException("HttpStream has been closed.");
}
if (completionCallback == null) {
throw new IllegalArgumentException("You must supply a completionCallback");
}
int error = httpStreamBaseWriteData(getNativeHandle(), data, endStream, completionCallback);
if (error != 0) {
int lastError = CRT.awsLastError();
throw new CrtRuntimeException(lastError);
}
}
/**
* Write data to an HTTP stream. Works for both HTTP/1.1 and HTTP/2.
* The stream must have been created with {@code useManualDataWrites = true}.
* You must call activate() before using this function.
*
* @param data data to send, or null to write zero bytes. Pass null with
* endStream=true to signal end-of-body without sending additional data.
* @param endStream if true, this is the last data to be sent on this stream.
* @return completable future which completes when data is flushed or an error occurs.
*/
public CompletableFuture<Void> writeData(final byte[] data, boolean endStream) {
CompletableFuture<Void> completionFuture = new CompletableFuture<>();
writeData(data, endStream, (errorCode) -> {
if (errorCode == 0) {
completionFuture.complete(null);
} else {
completionFuture.completeExceptionally(new CrtRuntimeException(errorCode));
}
});
return completionFuture;
}
/*******************************************************************************
* Native methods
******************************************************************************/
private static native void httpStreamBaseRelease(long http_stream);
private static native void httpStreamBaseIncrementWindow(long http_stream, int window_size);
private static native void httpStreamBaseActivate(long http_stream, HttpStreamBase streamObj);
private static native int httpStreamBaseGetResponseStatusCode(long http_stream);
private static native void httpStreamBaseCancelDefaultError(long http_stream);
private static native int httpStreamBaseWriteData(long http_stream, byte[] data, boolean endStream,
HttpStreamWriteDataCompletionCallback completionCallback);
}