use of okio.Sink in project okhttp by square.
the class InterceptorTest method uppercase.
private RequestBody uppercase(final RequestBody original) {
return new RequestBody() {
@Override
public MediaType contentType() {
return original.contentType();
}
@Override
public long contentLength() throws IOException {
return original.contentLength();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Sink uppercase = uppercase(sink);
BufferedSink bufferedSink = Okio.buffer(uppercase);
original.writeTo(bufferedSink);
bufferedSink.emit();
}
};
}
use of okio.Sink in project okhttp by square.
the class CallServerInterceptor method intercept.
@Override
public Response intercept(Chain chain) throws IOException {
HttpCodec httpCodec = ((RealInterceptorChain) chain).httpStream();
StreamAllocation streamAllocation = ((RealInterceptorChain) chain).streamAllocation();
Request request = chain.request();
long sentRequestMillis = System.currentTimeMillis();
httpCodec.writeRequestHeaders(request);
Response.Builder responseBuilder = null;
if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
// we did get (such as a 4xx response) without ever transmitting the request body.
if ("100-continue".equalsIgnoreCase(request.header("Expect"))) {
httpCodec.flushRequest();
responseBuilder = httpCodec.readResponseHeaders(true);
}
// Write the request body, unless an "Expect: 100-continue" expectation failed.
if (responseBuilder == null) {
Sink requestBodyOut = httpCodec.createRequestBody(request, request.body().contentLength());
BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
request.body().writeTo(bufferedRequestBody);
bufferedRequestBody.close();
}
}
httpCodec.finishRequest();
if (responseBuilder == null) {
responseBuilder = httpCodec.readResponseHeaders(false);
}
Response response = responseBuilder.request(request).handshake(streamAllocation.connection().handshake()).sentRequestAtMillis(sentRequestMillis).receivedResponseAtMillis(System.currentTimeMillis()).build();
int code = response.code();
if (forWebSocket && code == 101) {
// Connection is upgrading, but we need to ensure interceptors see a non-null response body.
response = response.newBuilder().body(Util.EMPTY_RESPONSE).build();
} else {
response = response.newBuilder().body(httpCodec.openResponseBody(response)).build();
}
if ("close".equalsIgnoreCase(response.request().header("Connection")) || "close".equalsIgnoreCase(response.header("Connection"))) {
streamAllocation.noNewStreams();
}
if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
throw new ProtocolException("HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
}
return response;
}
use of okio.Sink in project okhttp by square.
the class PublicSuffixListGenerator method main.
public static void main(String... args) throws IOException {
OkHttpClient client = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url("https://publicsuffix.org/list/public_suffix_list.dat").build();
SortedSet<ByteString> sortedRules = new TreeSet<>();
SortedSet<ByteString> sortedExceptionRules = new TreeSet<>();
try (Response response = client.newCall(request).execute()) {
BufferedSource source = response.body().source();
int totalRuleBytes = 0;
int totalExceptionRuleBytes = 0;
while (!source.exhausted()) {
String line = source.readUtf8LineStrict();
if (line.trim().isEmpty() || line.startsWith("//"))
continue;
if (line.contains(WILDCARD_CHAR)) {
assertWildcardRule(line);
}
ByteString rule = ByteString.encodeUtf8(line);
if (rule.startsWith(EXCEPTION_RULE_MARKER)) {
rule = rule.substring(1);
// We use '\n' for end of value.
totalExceptionRuleBytes += rule.size() + 1;
sortedExceptionRules.add(rule);
} else {
// We use '\n' for end of value.
totalRuleBytes += rule.size() + 1;
sortedRules.add(rule);
}
}
File resources = new File(OKHTTP_RESOURCE_DIR);
if (!resources.mkdirs() && !resources.exists()) {
throw new RuntimeException("Unable to create resource directory!");
}
Sink fileSink = Okio.sink(new File(resources, PublicSuffixDatabase.PUBLIC_SUFFIX_RESOURCE));
try (BufferedSink sink = Okio.buffer(new GzipSink(fileSink))) {
sink.writeInt(totalRuleBytes);
for (ByteString domain : sortedRules) {
sink.write(domain).writeByte('\n');
}
sink.writeInt(totalExceptionRuleBytes);
for (ByteString domain : sortedExceptionRules) {
sink.write(domain).writeByte('\n');
}
}
}
}
use of okio.Sink in project okhttp by square.
the class CacheInterceptor method cacheWritingResponse.
/**
* Returns a new source that writes bytes to {@code cacheRequest} as they are read by the source
* consumer. This is careful to discard bytes left over when the stream is closed; otherwise we
* may never exhaust the source stream and therefore not complete the cached response.
*/
private Response cacheWritingResponse(final CacheRequest cacheRequest, Response response) throws IOException {
// Some apps return a null body; for compatibility we treat that like a null cache request.
if (cacheRequest == null)
return response;
Sink cacheBodyUnbuffered = cacheRequest.body();
if (cacheBodyUnbuffered == null)
return response;
final BufferedSource source = response.body().source();
final BufferedSink cacheBody = Okio.buffer(cacheBodyUnbuffered);
Source cacheWritingSource = new Source() {
boolean cacheRequestClosed;
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead;
try {
bytesRead = source.read(sink, byteCount);
} catch (IOException e) {
if (!cacheRequestClosed) {
cacheRequestClosed = true;
// Failed to write a complete cache response.
cacheRequest.abort();
}
throw e;
}
if (bytesRead == -1) {
if (!cacheRequestClosed) {
cacheRequestClosed = true;
// The cache response is complete!
cacheBody.close();
}
return -1;
}
sink.copyTo(cacheBody.buffer(), sink.size() - bytesRead, bytesRead);
cacheBody.emitCompleteSegments();
return bytesRead;
}
@Override
public Timeout timeout() {
return source.timeout();
}
@Override
public void close() throws IOException {
if (!cacheRequestClosed && !discard(this, HttpCodec.DISCARD_STREAM_TIMEOUT_MILLIS, MILLISECONDS)) {
cacheRequestClosed = true;
cacheRequest.abort();
}
source.close();
}
};
return response.newBuilder().body(new RealResponseBody(response.headers(), Okio.buffer(cacheWritingSource))).build();
}
use of okio.Sink in project okhttp by square.
the class WebSocketWriterTest method noWritesAfterClose.
@Test
public void noWritesAfterClose() throws IOException {
Sink sink = serverWriter.newMessageSink(OPCODE_TEXT, -1);
sink.close();
assertData("8100");
Buffer payload = new Buffer().writeUtf8("Hello");
try {
// Write to the unbuffered sink as BufferedSink keeps its own closed state.
sink.write(payload, payload.size());
fail();
} catch (IOException e) {
assertEquals("closed", e.getMessage());
}
}
Aggregations