@Test
  public void testThrowExceptionIfReturnOriginalContentOnErrorNotSet() throws Exception {
    String url = "http://example.org/mypage.html";
    String domain = "example.org";

    setupProxyRequestMock(domain, url, true, -1, null, null);

    String contentType = "text/html; charset=UTF-8";
    HttpResponse resp =
        new HttpResponseBuilder()
            .setResponseString("Hello")
            .addHeader("Content-Type", contentType)
            .create();

    expect(pipeline.execute((HttpRequest) EasyMock.anyObject())).andReturn(resp);

    replay();

    final StringBuilder stringBuilder = new StringBuilder("");
    ResponseRewriter rewriter = getResponseRewriterThatThrowsExceptions(stringBuilder);

    ResponseRewriterRegistry rewriterRegistry =
        new DefaultResponseRewriterRegistry(Arrays.<ResponseRewriter>asList(rewriter), null);
    ProxyHandler proxyHandler = new ProxyHandler(pipeline, rewriterRegistry, true);

    boolean exceptionCaught = false;
    try {
      proxyHandler.fetch(request);
    } catch (GadgetException e) {
      exceptionCaught = true;
      assertEquals(404, e.getHttpStatusCode());
    }
    assertTrue(exceptionCaught);
    assertEquals("exceptionThrown", stringBuilder.toString());
  }
  // ProxyHandler throws INTERNAL_SERVER_ERRORS without isRecoverable() check.
  @Test
  public void testRecoverableRewritingException() throws Exception {
    String url = "http://example.org/mypage.html";
    String domain = "example.org";

    setupProxyRequestMock(domain, url, true, -1, null, null);

    String contentType = "text/html; charset=UTF-8";
    HttpResponse resp =
        new HttpResponseBuilder()
            .setResponseString("Hello")
            .addHeader("Content-Type", contentType)
            .create();

    expect(pipeline.execute((HttpRequest) EasyMock.anyObject())).andReturn(resp);

    replay();

    final StringBuilder stringBuilder = new StringBuilder("");
    ResponseRewriter rewriter = getResponseRewriterThatThrowsExceptions(stringBuilder);

    ResponseRewriterRegistry rewriterRegistry =
        new DefaultResponseRewriterRegistry(Arrays.<ResponseRewriter>asList(rewriter), null);
    ProxyHandler proxyHandler = new ProxyHandler(pipeline, rewriterRegistry, true);

    request.setReturnOriginalContentOnError(true);
    HttpResponse recorder = proxyHandler.fetch(request);

    verify();

    // Ensure that original content is returned.
    assertEquals(recorder.getHeader("Content-Type"), contentType);
    assertEquals("Hello", recorder.getResponseAsString());
    assertEquals("exceptionThrown", stringBuilder.toString());
  }
  private void expectMime(String expectedMime, String contentMime, String outputMime)
      throws Exception {
    String url =
        "http://example.org/file.img?" + Param.REWRITE_MIME_TYPE.getKey() + '=' + expectedMime;
    String domain = "example.org";

    setupProxyRequestMock(domain, url, false, -1, expectedMime, null);

    HttpRequest req = new HttpRequest(Uri.parse(url)).setRewriteMimeType(expectedMime);

    HttpResponse resp =
        new HttpResponseBuilder()
            .setResponseString("Hello")
            .addHeader("Content-Type", contentMime)
            .create();

    expect(pipeline.execute(req)).andReturn(resp);

    replay();
    HttpResponse response = proxyHandler.fetch(request);
    verify();

    assertEquals(outputMime, response.getHeader("Content-Type"));
    reset();
  }
  @Test
  public void testInvalidHeaderDropped() throws Exception {
    String url = "http://example.org/mypage.html";
    String domain = "example.org";

    setupProxyRequestMock(domain, url, true, -1, null, null);

    HttpRequest req = new HttpRequest(Uri.parse(url)).setIgnoreCache(true);
    String contentType = "text/html; charset=UTF-8";
    HttpResponse resp =
        new HttpResponseBuilder()
            .setResponseString("Hello")
            .addHeader("Content-Type", contentType)
            .addHeader("Content-Length", "200") // Disallowed header.
            .addHeader(":", "someDummyValue") // Invalid header name.
            .create();

    expect(pipeline.execute(req)).andReturn(resp);

    replay();

    HttpResponse recorder = proxyHandler.fetch(request);

    verify();
    assertNull(recorder.getHeader(":"));
    assertNull(recorder.getHeader("Content-Length"));
    assertEquals(recorder.getHeader("Content-Type"), contentType);
  }
  @Test(expected = GadgetException.class)
  public void testNoUrl() throws Exception {
    setupNoArgsProxyRequestMock("www.example.com", null);
    replay();

    proxyHandler.fetch(request);
    fail("Proxy should raise exception if there is no url");
  }
  @Test
  public void testLockedDomainEmbed() throws Exception {
    setupNoArgsProxyRequestMock("www.example.com", URL_ONE);
    expectGetAndReturnData(URL_ONE, DATA_ONE.getBytes());

    replay();
    HttpResponse response = proxyHandler.fetch(request);
    verify();

    assertEquals(DATA_ONE, response.getResponseAsString());
    assertTrue(rewriter.responseWasRewritten());
  }
  @Test
  public void testWithBadTtl() throws Exception {
    String url = "http://example.org/file.evil";
    String domain = "example.org";

    setupProxyRequestMock(domain, url, false, -1, null, null);

    HttpRequest req = new HttpRequestCache(Uri.parse(url)).setCacheTtl(-1).setIgnoreCache(false);
    HttpResponse resp = new HttpResponse("Hello");
    expect(pipeline.execute(req)).andReturn(resp);

    replay();
    proxyHandler.fetch(request);
    verify();
  }
  @Test
  public void testOctetSetOnNullContentType() throws Exception {
    String url = "http://example.org/file.evil";
    String domain = "example.org";

    setupNoArgsProxyRequestMock(domain, url);
    expectGetAndReturnHeaders(url, Maps.<String, List<String>>newHashMap());

    replay();
    HttpResponse response = proxyHandler.fetch(request);
    verify();

    assertEquals("application/octet-stream", response.getHeader("Content-Type"));
    assertNotNull(response.getHeader("Content-Disposition"));
    assertTrue(rewriter.responseWasRewritten());
  }
  private void assertNoContentDispositionForFlash(String contentType) throws Exception {
    // Some headers may be blacklisted. These are OK.
    String url = "http://example.org/file.evil";
    String domain = "example.org";
    Map<String, List<String>> headers = ImmutableMap.of("Content-Type", Arrays.asList(contentType));

    setupNoArgsProxyRequestMock(domain, url);
    expectGetAndReturnHeaders(url, headers);

    replay();
    HttpResponse response = proxyHandler.fetch(request);
    verify();

    assertEquals(contentType, response.getHeader("Content-Type"));
    assertNull(response.getHeader("Content-Disposition"));
    assertTrue(rewriter.responseWasRewritten());
  }
  @Test
  public void testGetFallback() throws Exception {
    String url = "http://example.org/file.evil";
    String domain = "example.org";
    String fallback_url = "http://fallback.com/fallback.png";

    setupProxyRequestMock(domain, url, true, -1, null, fallback_url);

    HttpRequest req = new HttpRequest(Uri.parse(url)).setIgnoreCache(true);
    HttpResponse resp = HttpResponse.error();
    HttpResponse fallback_resp = new HttpResponse("Fallback");
    expect(pipeline.execute(req)).andReturn(resp);
    expect(pipeline.execute(isA(HttpRequest.class))).andReturn(fallback_resp);

    replay();
    proxyHandler.fetch(request);
    verify();
  }
  @Test
  public void testHttpRequestFillsParentAndContainer() throws Exception {
    setupNoArgsProxyRequestMock("www.example.com", URL_ONE);
    // HttpRequest req = new HttpRequest(Uri.parse(URL_ONE));
    HttpResponse resp = new HttpResponseBuilder().setResponse(DATA_ONE.getBytes()).create();

    Capture<HttpRequest> httpRequest = new Capture<HttpRequest>();
    expect(pipeline.execute(capture(httpRequest))).andReturn(resp);

    replay();
    HttpResponse response = proxyHandler.fetch(request);
    verify();

    // Check that the HttpRequest passed in has all the relevant fields sets
    assertEquals("default", httpRequest.getValue().getContainer());
    assertEquals(Uri.parse(URL_ONE), httpRequest.getValue().getUri());

    assertEquals(DATA_ONE, response.getResponseAsString());
    assertTrue(rewriter.responseWasRewritten());
  }
  @Test
  public void testHeadersPreserved() throws Exception {
    // Some headers may be blacklisted. These are OK.
    String url = "http://example.org/file.evil";
    String domain = "example.org";
    String contentType = "text/evil; charset=UTF-8";
    String magicGarbage = "fadfdfdfd";
    Map<String, List<String>> headers = Maps.newHashMap();
    headers.put("Content-Type", Arrays.asList(contentType));
    headers.put("X-Magic-Garbage", Arrays.asList(magicGarbage));

    setupNoArgsProxyRequestMock(domain, url);
    expectGetAndReturnHeaders(url, headers);

    replay();
    HttpResponse response = proxyHandler.fetch(request);
    verify();

    assertEquals(contentType, response.getHeader("Content-Type"));
    assertEquals(magicGarbage, response.getHeader("X-Magic-Garbage"));
    assertTrue(rewriter.responseWasRewritten());
  }
 @Override
 protected void doGet(HttpServletRequest request, HttpServletResponse response)
     throws IOException {
   if (request.getHeader("If-Modified-Since") != null) {
     response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
     return;
   }
   if (request.getParameter(ProxyBase.REWRITE_MIME_TYPE_PARAM) != null) {
     response.setHeader("Content-Type", request.getParameter(ProxyBase.REWRITE_MIME_TYPE_PARAM));
   }
   if (request.getParameter(ProxyBase.REFRESH_PARAM) != null) {
     HttpUtil.setCachingHeaders(
         response, Integer.valueOf(request.getParameter(ProxyBase.REFRESH_PARAM)));
   }
   response.setHeader("Content-Disposition", "attachment;filename=p.txt");
   ResponseWrapper wrapper = new ResponseWrapper(response);
   for (int i = 1; i < Integer.MAX_VALUE; i++) {
     String url = request.getParameter(Integer.toString(i));
     if (url == null) {
       break;
     }
     try {
       wrapper.getOutputStream().println("/* ---- Start " + url + " ---- */");
       proxyHandler.fetch(new RequestWrapper(request, url), wrapper);
       wrapper.getOutputStream().println("/* ---- End " + url + " ---- */");
     } catch (GadgetException ge) {
       if (ge.getCode() != GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT) {
         outputError(ge, url, response);
         return;
       } else {
         wrapper.getOutputStream().println("/* ---- End " + url + " 404 ---- */");
       }
     }
   }
   response.setStatus(200);
 }