Update network service.

R=blundell@chromium.org

Review URL: https://codereview.chromium.org/1153933003
diff --git a/examples/go/BUILD.gn b/examples/go/BUILD.gn
index 265ebcc..842a533 100644
--- a/examples/go/BUILD.gn
+++ b/examples/go/BUILD.gn
@@ -10,7 +10,9 @@
       ":go_echo_client",
       ":go_echo_server",
       ":go_http_handler",
-      ":go_http_server",
+
+      # TODO(rogulenko): Re-enable when the go bindings generator supports it.
+      # ":go_http_server",
     ]
   }
 
diff --git a/mojo/public/tools/NETWORK_SERVICE_VERSION b/mojo/public/tools/NETWORK_SERVICE_VERSION
index 79a193f..073652f 100644
--- a/mojo/public/tools/NETWORK_SERVICE_VERSION
+++ b/mojo/public/tools/NETWORK_SERVICE_VERSION
@@ -1 +1 @@
-050294719f6890ceea4b27540d66295fe6e710a3
\ No newline at end of file
+29589023ac69014140b5bd1b162b77ed08ec8ddb
diff --git a/mojo/services/network/public/interfaces/BUILD.gn b/mojo/services/network/public/interfaces/BUILD.gn
index c13dfb5..adf3c5f 100644
--- a/mojo/services/network/public/interfaces/BUILD.gn
+++ b/mojo/services/network/public/interfaces/BUILD.gn
@@ -18,6 +18,7 @@
     "tcp_server_socket.mojom",
     "udp_socket.mojom",
     "url_loader.mojom",
+    "url_loader_interceptor.mojom",
     "web_socket.mojom",
   ]
 
diff --git a/mojo/services/network/public/interfaces/network_service.mojom b/mojo/services/network/public/interfaces/network_service.mojom
index 6467c7f..f8ab7e2 100644
--- a/mojo/services/network/public/interfaces/network_service.mojom
+++ b/mojo/services/network/public/interfaces/network_service.mojom
@@ -12,6 +12,7 @@
 import "network/public/interfaces/tcp_connected_socket.mojom";
 import "network/public/interfaces/udp_socket.mojom";
 import "network/public/interfaces/url_loader.mojom";
+import "network/public/interfaces/url_loader_interceptor.mojom";
 import "network/public/interfaces/web_socket.mojom";
 
 // TODO Darin suggests that this should probably be two classes. One for
@@ -72,4 +73,9 @@
                    HttpServerDelegate delegate)
       => (NetworkError result,
           NetAddress? bound_to);
+
+  // Register a new url loader interceptor that will be used on any new
+  // URLLoader. Interceptor are chained. The last registed interceptor will
+  // received the requests first and the responses last.
+  RegisterURLLoaderInterceptor(URLLoaderInterceptorFactory factory);
 };
diff --git a/mojo/services/network/public/interfaces/url_loader_interceptor.mojom b/mojo/services/network/public/interfaces/url_loader_interceptor.mojom
new file mode 100644
index 0000000..bd3eb04
--- /dev/null
+++ b/mojo/services/network/public/interfaces/url_loader_interceptor.mojom
@@ -0,0 +1,53 @@
+// 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.
+
+module mojo;
+
+import "mojo/public/interfaces/network/url_request.mojom";
+import "mojo/public/interfaces/network/url_response.mojom";
+
+// Factory for |URLLoaderInterceptor|. The factory is called once per URLLoader
+// and will be associated to it.
+interface URLLoaderInterceptorFactory {
+  Create(URLLoaderInterceptor& interceptor);
+};
+
+// An |URLLoaderInterceptor| is associated to a single URLLoader. It will be
+// able to intercept requests sent to the URLLoader and transform these or
+// directly respond to it. It will also intercept responses and transform them
+// or ask the network to continue with another request instead.
+// In case of redirect, the behavior is the following:
+// - If in the request |auto_follow_redirects| is true, the interceptor doesn't
+//   have access to any of the intermediate request(s) or response(s).
+//   Otherwise, it has access to intermediate responses as they are sent to the
+//   client and it is also notified when the client asks to follow a redirect.
+interface URLLoaderInterceptor {
+  // Intercept a request before it is sent to the network. This method can
+  // transform the request by returning the new requests to consider, or
+  // respond to the request itself by returning a response.
+  InterceptRequest(URLRequest request) =>
+      (URLLoaderInterceptorResponse response);
+
+  // Intercept |URLLoader.FollowRedirect()| calls. This method can either
+  // return null to let the call through, return a request to change the
+  // redirect, or respond to the redirect itself by returning a response.
+  InterceptFollowRedirect() => (URLLoaderInterceptorResponse? response);
+
+  // Intercept a response before it is sent to the loader client. This method
+  // can transform the response by returning the new response to send, ask
+  // the loader to load a new request instead by returning the request to load,
+  // or if the response is a redirect, follow it by returning null.
+  InterceptResponse(URLResponse response) =>
+      (URLLoaderInterceptorResponse? response);
+};
+
+// Response for the intercept methods. One and only one of the two fields
+// must be set. If |request| is set, the url loader will execute the request.
+// If |response| is set, the url loader will send it to its client. It is the
+// responsibility of the interceptor not to create infinite loops.
+// TODO(qsr): Change this to an union.
+struct URLLoaderInterceptorResponse {
+  URLRequest? request;
+  URLResponse? response;
+};
diff --git a/sky/services/oknet/src/org/domokit/oknet/NetworkServiceImpl.java b/sky/services/oknet/src/org/domokit/oknet/NetworkServiceImpl.java
index 8919c55..0f87957 100644
--- a/sky/services/oknet/src/org/domokit/oknet/NetworkServiceImpl.java
+++ b/sky/services/oknet/src/org/domokit/oknet/NetworkServiceImpl.java
@@ -23,6 +23,7 @@
 import org.chromium.mojom.mojo.TcpConnectedSocket;
 import org.chromium.mojom.mojo.UdpSocket;
 import org.chromium.mojom.mojo.UrlLoader;
+import org.chromium.mojom.mojo.UrlLoaderInterceptorFactory;
 import org.chromium.mojom.mojo.WebSocket;
 
 import java.io.File;
@@ -110,4 +111,9 @@
             CreateHttpServerResponse callback) {
         delegate.close();
     }
+
+    @Override
+    public void registerUrlLoaderInterceptor(UrlLoaderInterceptorFactory factory) {
+        factory.close();
+    }
 }