Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(806)

Unified Diff: sky/services/oknet/src/org/domokit/oknet/UrlLoaderImpl.java

Issue 930673002: Add an implementation of url_loader.mojom using OkHttp (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: update copyright Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sky/services/oknet/src/org/domokit/oknet/NetworkServiceImpl.java ('k') | sky/shell/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/services/oknet/src/org/domokit/oknet/UrlLoaderImpl.java
diff --git a/sky/services/oknet/src/org/domokit/oknet/UrlLoaderImpl.java b/sky/services/oknet/src/org/domokit/oknet/UrlLoaderImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..b3d2b079b388e59960ad1f6cf270ce0ed76aa4b1
--- /dev/null
+++ b/sky/services/oknet/src/org/domokit/oknet/UrlLoaderImpl.java
@@ -0,0 +1,196 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.domokit.oknet;
+
+import com.squareup.okhttp.Call;
+import com.squareup.okhttp.Callback;
+import com.squareup.okhttp.Headers;
+import com.squareup.okhttp.MediaType;
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Response;
+import com.squareup.okhttp.ResponseBody;
+
+import org.chromium.mojo.system.AsyncWaiter;
+import org.chromium.mojo.system.Core;
+import org.chromium.mojo.system.DataPipe;
+import org.chromium.mojo.system.MojoException;
+import org.chromium.mojo.system.MojoResult;
+import org.chromium.mojo.system.Pair;
+import org.chromium.mojom.mojo.NetworkError;
+import org.chromium.mojom.mojo.UrlLoader;
+import org.chromium.mojom.mojo.UrlLoaderStatus;
+import org.chromium.mojom.mojo.UrlRequest;
+import org.chromium.mojom.mojo.UrlResponse;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+import okio.BufferedSource;
+
+/**
+ * OkHttp implementation of UrlLoader.
+ */
+public class UrlLoaderImpl implements UrlLoader {
+ private Core mCore;
+ private OkHttpClient mClient;
+ private boolean mIsLoading;
+ private NetworkError mError;
+
+ class CopyToPipeJob {
+ private BufferedSource mSource;
+ private DataPipe.ProducerHandle mProducer;
+
+ public CopyToPipeJob(BufferedSource source, DataPipe.ProducerHandle producerHandle) {
+ mSource = source;
+ mProducer = producerHandle;
+ }
+
+ public void copy() throws IOException {
+ int result = 0;
+ do {
+ try {
+ ByteBuffer buffer = mProducer.beginWriteData(0, DataPipe.WriteFlags.none());
+ // TODO(abarth): There must be a way to do this without the temporary buffer.
+ byte[] tmp = new byte[buffer.capacity()];
+ result = mSource.read(tmp);
+ buffer.put(tmp);
+ mProducer.endWriteData(result == -1 ? 0 : result);
+ } catch (MojoException e) {
+ if (e.getMojoResult() != MojoResult.SHOULD_WAIT) throw e;
+ copyMoreAsync();
+ return;
+ }
+ } while (result != -1);
+
+ mIsLoading = false;
+ mProducer.close();
+ }
+
+ private void copyMoreAsync() {
+ AsyncWaiter w = mCore.getDefaultAsyncWaiter();
+ w.asyncWait(mProducer, Core.HandleSignals.WRITABLE, -1, new AsyncWaiter.Callback() {
+ @Override
+ public void onResult(int result) {
+ assert result == MojoResult.OK;
+ try {
+ copy();
+ } catch (IOException e) {
+ mIsLoading = false;
+ mProducer.close();
+ }
+ }
+ @Override
+ public void onError(MojoException exception) {
+ mIsLoading = false;
+ mProducer.close();
+ }
+ });
+ }
+ }
+
+ public UrlLoaderImpl(Core core, OkHttpClient client) {
+ assert core != null;
+ mCore = core;
+ mClient = client;
+ mIsLoading = false;
+ mError = null;
+ }
+
+ @Override
+ public void close() {}
+
+ @Override
+ public void onConnectionError(MojoException e) {}
+
+ @Override
+ public void start(UrlRequest request, StartResponse callback) {
+ mIsLoading = true;
+ mError = null;
+
+ Request.Builder builder =
+ new Request.Builder().url(request.url).method(request.method, null);
+
+ if (request.headers != null) {
+ for (String header : request.headers) {
+ String[] parts = header.split(":");
+ String name = parts[0].trim();
+ String value = parts.length > 1 ? parts[2].trim() : "";
+ builder.addHeader(name, value);
+ }
+ }
+
+ // TODO(abarth): body, responseBodyBufferSize, autoFollowRedirects, bypassCache.
+ final StartResponse responseCallback = callback;
+ Call call = mClient.newCall(builder.build());
+ call.enqueue(new Callback() {
+ @Override
+ public void onFailure(Request request, IOException e) {
+ mError = new NetworkError();
+ // TODO(abarth): Which mError.code should we set?
jamesr 2015/02/18 23:38:02 the codes are actually defined as a mojom enumerat
+ mError.description = e.toString();
+ UrlResponse urlResponse = new UrlResponse();
+ urlResponse.error = mError;
+ responseCallback.call(urlResponse);
+
+ mIsLoading = false;
+ }
+
+ @Override
+ public void onResponse(Response response) {
+ UrlResponse urlResponse = new UrlResponse();
+ urlResponse.url = response.request().urlString();
+ urlResponse.statusCode = response.code();
+ urlResponse.statusLine = response.message();
+
+ Headers headers = response.headers();
+ urlResponse.headers = new String[headers.size()];
+ for (int i = 0; i < headers.size(); ++i) {
+ String name = headers.name(i);
+ String value = headers.value(i);
+ urlResponse.headers[i] = name + ": " + value;
+ }
+
+ ResponseBody body = response.body();
+ MediaType mediaType = body.contentType();
+ if (mediaType != null) {
+ urlResponse.mimeType = mediaType.type() + "/" + mediaType.subtype();
+ Charset charset = mediaType.charset();
+ if (charset != null)
+ urlResponse.charset = charset.displayName();
+ }
+
+ Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles =
+ mCore.createDataPipe(null);
+ DataPipe.ProducerHandle producerHandle = handles.first;
+ DataPipe.ConsumerHandle consumerHandle = handles.second;
+ urlResponse.body = consumerHandle;
+ responseCallback.call(urlResponse);
+ CopyToPipeJob job = new CopyToPipeJob(body.source(), producerHandle);
+ try {
+ job.copy();
+ } catch (IOException e) {
+ mIsLoading = false;
+ producerHandle.close();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void followRedirect(FollowRedirectResponse callback) {
+ // TODO(abarth): Implement redirects.
+ callback.call(new UrlResponse());
+ }
+
+ @Override
+ public void queryStatus(QueryStatusResponse callback) {
+ UrlLoaderStatus status = new UrlLoaderStatus();
+ status.error = mError;
+ status.isLoading = mIsLoading;
+ callback.call(status);
+ }
+}
« no previous file with comments | « sky/services/oknet/src/org/domokit/oknet/NetworkServiceImpl.java ('k') | sky/shell/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698