diff --git a/src/com/google/enterprise/adaptor/ReverseProxyHandler.java b/src/com/google/enterprise/adaptor/ReverseProxyHandler.java
new file mode 100644
index 0000000..13c57fc
--- /dev/null
+++ b/src/com/google/enterprise/adaptor/ReverseProxyHandler.java
@@ -0,0 +1,266 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.enterprise.adaptor;
+
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Sets;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Authenticator;
+import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * An HTTP reverse proxy. This class uses HttpURLConnection internally, so the
+ * default {@link Authenticator} must be {@code null} for proper operation. The
+ * implementation is known to drop the response body for 401 responses to POST
+ * requests.
+ */
+class ReverseProxyHandler implements HttpHandler {
+  // The Hop-by-hop headers that are connection-local, as defined by RFC 2616
+  // Section 13.5.1. As mentioned in the section, additional headers can be
+  // specified in the Connection header.
+  private static final Set<String> PREDEFINED_HOP_BY_HOP_HEADERS
+      = ImmutableSortedSet.orderedBy(String.CASE_INSENSITIVE_ORDER).add(
+          "Connection",
+          "Host", // Because this is a reverse proxy.
+          "Keep-Alive",
+          "Proxy-Authenticate",
+          "Proxy-Authorization",
+          "TE",
+          "Trailers",
+          "Transfer-Encoding",
+          "Upgrade").build();
+
+  private static final Logger log
+      = Logger.getLogger(HttpExchanges.class.getName());
+
+  private final URI destinationBase;
+
+  public ReverseProxyHandler(URI destinationBase) {
+    if (destinationBase == null) {
+      throw new NullPointerException();
+    }
+    this.destinationBase = destinationBase;
+  }
+
+  @Override
+  public void handle(HttpExchange ex) throws IOException {
+    URI dest = computeProxyDestination(ex);
+
+    // Set up request
+    HttpURLConnection conn = (HttpURLConnection) dest.toURL().openConnection();
+    conn.setRequestMethod(ex.getRequestMethod());
+    conn.setAllowUserInteraction(false);
+    conn.setInstanceFollowRedirects(false);
+    // This adds Cache-Control: no-cache and Pragma: no-cache if those headers
+    // keys aren't already there. It is unfortunate that it modifies the
+    // request, however, the presense of these headers shouldn't have an impact
+    // because they are targeted to proxy servers, not the application server.
+    // See RFC 2616 Section 14.9.1 and 14.32.
+    conn.setUseCaches(false);
+    // HttpUrlConnection will add Accept and User-Agent headers if they aren't
+    // already there. Luckily they are almost always there.
+    copyRequestHeaders(ex, conn);
+    conn.addRequestProperty("X-Forwarded-For", getClientIp(ex));
+
+    // As defined in RFC 2616 Section 4.3
+    boolean hasRequestBody
+        = ex.getRequestHeaders().containsKey("Content-Length")
+        || ex.getRequestHeaders().containsKey("Transfer-Encoding");
+
+    conn.setDoOutput(hasRequestBody);
+    // Input is required for getResponseCode()
+    conn.setDoInput(true);
+
+    if (hasRequestBody) {
+      String strContentLength
+          = ex.getRequestHeaders().getFirst("Content-Length");
+      long contentLength = -1;
+      if (strContentLength != null) {
+        try {
+          contentLength = Long.parseLong(strContentLength);
+        } catch (NumberFormatException e) {
+          // Keep contentLength = -1
+        }
+      }
+      // Enable streaming mode on the connection to prevent entire request body
+      // from being buffered. Streaming mode also disables automatic
+      // authentication.
+      if (contentLength < 0) {
+        conn.setChunkedStreamingMode(-1);
+      } else {
+        // TODO(ejona): remove cast once we depend on Java 7.
+        conn.setFixedLengthStreamingMode((int) contentLength);
+      }
+    } else {
+      // It is essential that no authentication happens. Unfortunately for
+      // requests with no body (like GET), it seems impossible to detect if
+      // authentication could be or was performed and impossible to prevent it
+      // for a particular request.
+      //
+      // Thus, we disable authentication globally, which could easily break
+      // other code's assumptions. However, the hope is that the other code will
+      // begin breaking and we have a chance at discovering the incompatibility
+      // between the two pieces of code, instead of silently offering content to
+      // requesters that they are not authenticated for.
+      Authenticator.setDefault(null);
+    }
+
+    // Actually issue the request, and copy the data back
+    conn.connect();
+    if (hasRequestBody) {
+      try {
+        IOHelper.copyStream(ex.getRequestBody(), conn.getOutputStream());
+        ex.getRequestBody().close();
+        conn.getOutputStream().close();
+      } catch (IOException e) {
+        // TODO(ejona): determine if there is a more graceful way to clean up
+        conn.disconnect();
+        throw e;
+      }
+    }
+
+    InputStream inputStream = conn.getResponseCode() >= 400
+        ? conn.getErrorStream() : conn.getInputStream();
+    // InputStream is null when responseCode == 401 and doing streaming, because
+    // HttpURLConnection does not consider its state "connected". Unfortunately,
+    // that means that we will lose the content for 401 responses for POST.
+    if (conn.getResponseCode() == 401 && inputStream == null) {
+      inputStream = new ByteArrayInputStream(new byte[0]);
+    }
+
+    // As defined in RFC 2616 Section 4.3
+    boolean hasResponseBody = !("HEAD".equalsIgnoreCase(ex.getRequestMethod())
+        || conn.getResponseCode() / 100 == 1 // 1xx Informational
+        || conn.getResponseCode() == 204 // No Content
+        || conn.getResponseCode() == 304); // Not Modified
+
+    try {
+      copyResponseHeaders(conn, ex);
+
+      if (!hasResponseBody) {
+        ex.sendResponseHeaders(conn.getResponseCode(), -1);
+      } else {
+        int contentLength = conn.getContentLength();
+        if (contentLength <= 0) {
+          // If the content length was unknown (-1) or if it was zero, then we
+          // are forced to use chunked transfer encoding.
+          contentLength = 0;
+        }
+        ex.sendResponseHeaders(conn.getResponseCode(), contentLength);
+        IOHelper.copyStream(inputStream, ex.getResponseBody());
+      }
+      // Don't close in a finally because that would be a successful response.
+      // If there is an error we want the server to kill the connection, which
+      // informs the client that something went wrong.
+      ex.close();
+    } finally {
+      inputStream.close();
+    }
+  }
+
+  /**
+   * Compute the URI the proxy should send a request to, to proxy the provided
+   * request.
+   */
+  private URI computeProxyDestination(HttpExchange ex) {
+    URI req = HttpExchanges.getRequestUri(ex);
+    final String basePath = ex.getHttpContext().getPath();
+    if (!req.getPath().startsWith(basePath)) {
+      throw new AssertionError();
+    }
+    String lastPartOfPath = req.getPath().substring(basePath.length());
+    try {
+      return new URI(destinationBase.getScheme(),
+          destinationBase.getAuthority(),
+          destinationBase.getPath() + lastPartOfPath, req.getQuery(),
+          req.getFragment());
+    } catch (URISyntaxException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  private void copyRequestHeaders(HttpExchange from, HttpURLConnection to) {
+    Set<String> requestHopByHopHeaders
+        = getHopByHopHeaders(from.getRequestHeaders().get("Connection"));
+    for (Map.Entry<String, List<String>> me
+        : from.getRequestHeaders().entrySet()) {
+      if (requestHopByHopHeaders.contains(me.getKey())) {
+        continue;
+      }
+      for (String value : me.getValue()) {
+        to.addRequestProperty(me.getKey(), value);
+      }
+    }
+  }
+
+  private void copyResponseHeaders(HttpURLConnection from, HttpExchange to) {
+    Set<String> responseHopByHopHeaders
+        = getHopByHopHeaders(from.getHeaderFields().get("Connection"));
+    // HttpURLConnection.getHeaderFields() reverses the order of repeated
+    // headers' values, so we avoid it. Specifically,
+    // sun.net.www.MessageHeader.filterAndAddHeaders() loops through the
+    // headers in reverse order while building the map.
+    for (int i = 0;; i++) {
+      String key = from.getHeaderFieldKey(i);
+      String value = from.getHeaderField(i);
+      if (value == null) {
+        break; // Reached end
+      }
+      if (key == null) {
+        continue; // Value is the HTTP status line, which we want to skip
+      }
+      if (responseHopByHopHeaders.contains(key)) {
+        continue;
+      }
+      to.getResponseHeaders().add(key, value);
+    }
+  }
+
+  private String getClientIp(HttpExchange ex) {
+    InetSocketAddress clientAddr = ex.getRemoteAddress();
+    if (clientAddr.isUnresolved()) {
+      log.log(Level.WARNING, "Could not determine client's IP");
+      return "unknown";
+    }
+    return clientAddr.getAddress().getHostAddress();
+  }
+
+  private Set<String> getHopByHopHeaders(List<String> connectionValues) {
+    List<String> rawConnectionHeaders
+        = HttpExchanges.splitHeaderValues(connectionValues);
+    if (rawConnectionHeaders == null) {
+      rawConnectionHeaders = Collections.emptyList();
+    }
+    Set<String> connectionHeaders
+        = ImmutableSortedSet.orderedBy(String.CASE_INSENSITIVE_ORDER)
+        .addAll(rawConnectionHeaders).build();
+    return Sets.union(PREDEFINED_HOP_BY_HOP_HEADERS, connectionHeaders);
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/MockHttpExchange.java b/test/com/google/enterprise/adaptor/MockHttpExchange.java
index f1139bd..f385aaf 100644
--- a/test/com/google/enterprise/adaptor/MockHttpExchange.java
+++ b/test/com/google/enterprise/adaptor/MockHttpExchange.java
@@ -24,6 +24,9 @@
  * Mock {@link HttpExchange} for testing.
  */
 public class MockHttpExchange extends HttpExchange {
+  public static final String HEADER_DATE_VALUE
+      = "Sun, 06 Nov 1994 08:49:37 GMT";
+
   private final String method;
   private final URI uri;
   private final Map<String, Object> attributes = new HashMap<String, Object>();
@@ -40,13 +43,14 @@
       = new ClosingFilterOutputStream(responseBodyOrig);
   private int responseCode = -1;
   private HttpContext httpContext;
+  private InetSocketAddress remoteAddress;
 
   public MockHttpExchange(String method, String path,
                           HttpContext context) {
     this(method, "localhost", path, context);
   }
 
-  private MockHttpExchange(String method, String host, String path,
+  public MockHttpExchange(String method, String host, String path,
       HttpContext context) {
     if (method == null || host == null || path == null) {
       throw new NullPointerException();
@@ -63,6 +67,14 @@
     }
     this.httpContext = context;
     getRequestHeaders().add("Host", host);
+
+    try {
+      remoteAddress = new InetSocketAddress(
+          InetAddress.getByAddress("remotehost", new byte[] {127, 0, 0, 3}),
+          65000);
+    } catch (UnknownHostException ex) {
+      throw new AssertionError(ex);
+    }
   }
 
   @Override
@@ -110,13 +122,11 @@
 
   @Override
   public InetSocketAddress getRemoteAddress() {
-    try {
-      return new InetSocketAddress(
-          InetAddress.getByAddress("remotehost", new byte[] {127, 0, 0, 3}),
-          65000);
-    } catch (UnknownHostException ex) {
-      throw new IllegalStateException(ex);
-    }
+    return remoteAddress;
+  }
+
+  public void setRemoteAddress(InetSocketAddress remoteAddress) {
+    this.remoteAddress = remoteAddress;
   }
 
   @Override
@@ -162,7 +172,8 @@
     if (responseCode != -1) {
       throw new IllegalStateException();
     }
-    getResponseHeaders().add("Date", "Sun, 06 Nov 1994 08:49:37 GMT");
+    // The handler gets no choice of the date.
+    getResponseHeaders().set("Date", HEADER_DATE_VALUE);
     responseCode = rCode;
     // TODO(ejona): handle responseLengeth
   }
@@ -191,6 +202,7 @@
   public void setRequestBody(InputStream i) {
     requestBodyOrig = i;
     requestBody = requestBodyOrig;
+    getRequestHeaders().add("Transfer-Encoding", "chunked");
   }
 
   public byte[] getResponseBytes() {
diff --git a/test/com/google/enterprise/adaptor/ReverseProxyHandlerTest.java b/test/com/google/enterprise/adaptor/ReverseProxyHandlerTest.java
new file mode 100644
index 0000000..a68a256
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/ReverseProxyHandlerTest.java
@@ -0,0 +1,305 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.enterprise.adaptor;
+
+import static org.junit.Assert.*;
+
+import com.google.common.base.Objects;
+import com.sun.net.httpserver.Headers;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+import org.junit.*;
+
+import java.io.*;
+import java.net.*;
+import java.nio.charset.Charset;
+import java.util.*;
+
+/** Unit tests for {@link ReverseProxyHandler}. */
+public class ReverseProxyHandlerTest {
+  private static final Charset charset = Charset.forName("UTF-8");
+
+  private HttpServer server;
+  private int port;
+  private HttpServerScope scope;
+  private HttpHandler handler;
+  private MockHttpContext context = new MockHttpContext("/proxy/");
+
+  @Before
+  public void startupServer() throws IOException {
+    server = HttpServer.create(new InetSocketAddress(0), 0);
+    port = server.getAddress().getPort();
+    server.start();
+    handler = new ReverseProxyHandler(
+        URI.create("http://localhost:" + port + "/"));
+  }
+
+  @After
+  public void shutdownServer() {
+    server.stop(0);
+  }
+
+  @Test
+  public void testGet() throws IOException {
+    byte[] response = "test response".getBytes(charset);
+    Headers goldenRequestHeaders = new Headers();
+    goldenRequestHeaders.add("Host", "localhost:" + port);
+    goldenRequestHeaders.add("X-Forwarded-For", "127.0.0.3");
+    goldenRequestHeaders.add("Accept", "text/html,text/plain,application/*");
+    goldenRequestHeaders.add("User-agent",
+        "gsa-crawler (Enterprise; E3-SOMETHING; nobody@google.com)");
+    // Added by HttpUrlConnection. Would prefer not to have them, but they are
+    // there.
+    goldenRequestHeaders.add("Cache-Control", "no-cache");
+    goldenRequestHeaders.add("Pragma", "no-cache");
+    // Connection-specific header by HttpUrlConnection. This is normal.
+    goldenRequestHeaders.add("Connection", "keep-alive");
+    Headers goldenResponseHeaders = new Headers();
+    goldenResponseHeaders.add("Date", MockHttpExchange.HEADER_DATE_VALUE);
+    goldenResponseHeaders.add("Example", "1");
+    goldenResponseHeaders.add("Example", "something2");
+    goldenResponseHeaders.add("Example", "3");
+    goldenResponseHeaders.add("Best-Header", "best_value");
+
+    Map<String, List<String>> responseHeaders
+        = new HashMap<String, List<String>>();
+    responseHeaders.put("Example", Arrays.asList("1", "something2", "3"));
+    responseHeaders.put("Best-Header", Arrays.asList("best_value"));
+    MockHttpHandler mockHandler
+        = new MockHttpHandler(200, response, responseHeaders);
+    server.createContext("/get", mockHandler);
+    MockHttpExchange ex = new MockHttpExchange("GET", "example.com",
+        "/proxy/get", context);
+    ex.getRequestHeaders().add("Accept", "text/html,text/plain,application/*");
+    ex.getRequestHeaders().add("User-agent",
+        "gsa-crawler (Enterprise; E3-SOMETHING; nobody@google.com)");
+    handler.handle(ex);
+
+    assertHeadersEquals(goldenRequestHeaders, mockHandler.getRequestHeaders());
+    assertEquals(200, ex.getResponseCode());
+    assertHeadersEquals(goldenResponseHeaders, ex.getResponseHeaders());
+    assertArrayEquals(response, ex.getResponseBytes());
+  }
+
+  @Test
+  public void testHead() throws IOException {
+    MockHttpHandler mockHandler = new MockHttpHandler(200, null);
+    server.createContext("/head", mockHandler);
+    MockHttpExchange ex = new MockHttpExchange("HEAD", "example.com",
+        "/proxy/head", context);
+    handler.handle(ex);
+
+    assertEquals(200, ex.getResponseCode());
+    assertArrayEquals(new byte[0], ex.getResponseBytes());
+  }
+
+  @Test
+  public void testPost() throws IOException {
+    byte[] request = "Are you still there?".getBytes(charset);
+    byte[] response = "Hello, world!".getBytes(charset);
+    MockHttpHandler mockHandler = new MockHttpHandler(200, response);
+    server.createContext("/post", mockHandler);
+    MockHttpExchange ex = new MockHttpExchange("POST", "example.com",
+        "/proxy/post", context);
+    ex.setRequestBody(request);
+    handler.handle(ex);
+
+    assertEquals(200, ex.getResponseCode());
+    assertArrayEquals(request, mockHandler.getRequestBytes());
+    assertArrayEquals(response, ex.getResponseBytes());
+  }
+
+  @Test
+  public void testProxyXForwardedFor() throws IOException {
+    MockHttpHandler mockHandler = new MockHttpHandler(200, null);
+    server.createContext("/get", mockHandler);
+    MockHttpExchange ex = new MockHttpExchange("HEAD", "example.com",
+        "/proxy/get", context);
+    ex.getRequestHeaders().add("X-Forwarded-For", "10.0.0.4");
+    handler.handle(ex);
+
+    assertEquals(200, ex.getResponseCode());
+    assertEquals(Arrays.asList("10.0.0.4", "127.0.0.3"),
+        mockHandler.getRequestHeaders().get("X-Forwarded-For"));
+  }
+
+  @Test
+  public void testIpv6Host() throws IOException {
+    MockHttpHandler mockHandler = new MockHttpHandler(200, null);
+    server.createContext("/get", mockHandler);
+    MockHttpExchange ex = new MockHttpExchange("HEAD", "example.com",
+        "/proxy/get", context);
+    ex.setRemoteAddress(new InetSocketAddress(
+        InetAddress.getByAddress("remotehost",
+          new byte[] {1, 2, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 15, 16}),
+        65000));
+    handler.handle(ex);
+
+    assertEquals(200, ex.getResponseCode());
+    assertEquals(Arrays.asList("102:0:0:8:0:0:0:f10"),
+        mockHandler.getRequestHeaders().get("X-Forwarded-For"));
+  }
+
+  @Test
+  public void test500() throws IOException {
+    byte[] response = "error!".getBytes(charset);
+    MockHttpHandler mockHandler = new MockHttpHandler(500, response);
+    server.createContext("/get", mockHandler);
+    MockHttpExchange ex = new MockHttpExchange("GET", "example.com",
+        "/proxy/get", context);
+    handler.handle(ex);
+
+    assertEquals(500, ex.getResponseCode());
+    assertArrayEquals(response, ex.getResponseBytes());
+  }
+
+  @Test
+  public void test404() throws IOException {
+    byte[] response = "not there".getBytes(charset);
+    MockHttpHandler mockHandler = new MockHttpHandler(404, response);
+    server.createContext("/get", mockHandler);
+    MockHttpExchange ex = new MockHttpExchange("GET", "example.com",
+        "/proxy/get", context);
+    handler.handle(ex);
+
+    assertEquals(404, ex.getResponseCode());
+    assertArrayEquals(response, ex.getResponseBytes());
+  }
+
+  @Test
+  public void test401Post() throws IOException {
+    byte[] request = "Are you still there?".getBytes(charset);
+    byte[] response = "not authorized".getBytes(charset);
+    byte[] response2 = "authorized".getBytes(charset);
+    MockHttpHandler mockHandler = new MockHttpHandler(401, response);
+    MockHttpHandler mockHandler2 = new MockHttpHandler(200, response2);
+    HttpHandler authHandler = new AuthHandler(mockHandler, mockHandler2);
+    server.createContext("/post", authHandler);
+    MockHttpExchange ex = new MockHttpExchange("POST", "example.com",
+        "/proxy/post", context);
+    ex.setRequestBody(request);
+    Authenticator.setDefault(new Authenticator() {
+      @Override
+      protected PasswordAuthentication getPasswordAuthentication() {
+        return new PasswordAuthentication("user", "pass".toCharArray());
+      }
+    });
+    try {
+      handler.handle(ex);
+    } finally {
+      Authenticator.setDefault(null);
+    }
+
+    assertEquals(401, ex.getResponseCode());
+    // The response body is known-broken due to HttpURLConnection.
+    assertArrayEquals(new byte[0], ex.getResponseBytes());
+    // However, the headers are properly captured.
+    assertTrue(ex.getResponseHeaders().containsKey("Www-Authenticate"));
+  }
+
+  @Test
+  public void test401GetAuthenticator() throws IOException {
+    byte[] response = "not authorized".getBytes(charset);
+    byte[] response2 = "authorized".getBytes(charset);
+    MockHttpHandler mockHandler = new MockHttpHandler(401, response);
+    MockHttpHandler mockHandler2 = new MockHttpHandler(200, response2);
+    HttpHandler authHandler = new AuthHandler(mockHandler, mockHandler2);
+    server.createContext("/get", authHandler);
+    MockHttpExchange ex = new MockHttpExchange("GET", "example.com",
+        "/proxy/get", context);
+    Authenticator.setDefault(new Authenticator() {
+      @Override
+      protected PasswordAuthentication getPasswordAuthentication() {
+        return new PasswordAuthentication("user", "pass".toCharArray());
+      }
+    });
+    try {
+      handler.handle(ex);
+    } finally {
+      Authenticator.setDefault(null);
+    }
+
+    assertEquals(401, ex.getResponseCode());
+    assertArrayEquals(response, ex.getResponseBytes());
+  }
+
+  @Test
+  public void test401GetNoAuthenticator() throws IOException {
+    byte[] response = "not authorized".getBytes(charset);
+    byte[] response2 = "authorized".getBytes(charset);
+    MockHttpHandler mockHandler = new MockHttpHandler(401, response);
+    MockHttpHandler mockHandler2 = new MockHttpHandler(200, response2);
+    HttpHandler authHandler = new AuthHandler(mockHandler, mockHandler2);
+    server.createContext("/get", authHandler);
+    MockHttpExchange ex = new MockHttpExchange("GET", "example.com",
+        "/proxy/get", context);
+    Authenticator.setDefault(null);
+    handler.handle(ex);
+
+    assertEquals(401, ex.getResponseCode());
+    assertArrayEquals(response, ex.getResponseBytes());
+  }
+
+  @Test
+  public void testRedirect() throws IOException {
+    byte[] response = "test response".getBytes(charset);
+    Headers goldenResponseHeaders = new Headers();
+    goldenResponseHeaders.add("Date", MockHttpExchange.HEADER_DATE_VALUE);
+    goldenResponseHeaders.add("Location", "http://example.com");
+
+    Map<String, List<String>> responseHeaders
+        = new HashMap<String, List<String>>();
+    responseHeaders.put("Location", Arrays.asList("http://example.com"));
+    MockHttpHandler mockHandler
+        = new MockHttpHandler(307, response, responseHeaders);
+    server.createContext("/get", mockHandler);
+    MockHttpExchange ex = new MockHttpExchange("GET", "example.com",
+        "/proxy/get", context);
+    handler.handle(ex);
+
+    assertEquals(307, ex.getResponseCode());
+    assertHeadersEquals(goldenResponseHeaders, ex.getResponseHeaders());
+    assertArrayEquals(response, ex.getResponseBytes());
+  }
+
+  private static void assertHeadersEquals(Headers golden, Headers header) {
+    if (!Objects.equal(golden, header)) {
+      fail("expected:" + new TreeMap<String, List<String>>(golden)
+          + " but was:" + new TreeMap<String, List<String>>(header));
+    }
+  }
+
+  private static class AuthHandler implements HttpHandler {
+    private final HttpHandler needToAuth;
+    private final HttpHandler authed;
+
+    public AuthHandler(HttpHandler needToAuth, HttpHandler authed) {
+      this.needToAuth = needToAuth;
+      this.authed = authed;
+    }
+
+    @Override
+    public void handle(HttpExchange ex) throws IOException {
+      if (ex.getRequestHeaders().containsKey("Authorization")) {
+        authed.handle(ex);
+      } else {
+        ex.getResponseHeaders().add("WWW-Authenticate", "Basic realm=\"test\"");
+        needToAuth.handle(ex);
+      }
+    }
+  }
+}
