@Test
  public void testTransparentProxyWithoutPrefix() throws Exception {
    final String target = "/test";
    prepareServer(
        new HttpServlet() {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
            if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true");
            resp.setStatus(target.equals(req.getRequestURI()) ? 200 : 404);
          }
        });

    final String proxyTo = "http://localhost:" + serverConnector.getLocalPort();
    proxyServlet = new ProxyServlet.Transparent();
    Map<String, String> initParams = new HashMap<>();
    initParams.put("proxyTo", proxyTo);
    prepareProxy(initParams);

    // Make the request to the proxy, it should transparently forward to the server
    ContentResponse response =
        client
            .newRequest("localhost", proxyConnector.getLocalPort())
            .path(target)
            .timeout(5, TimeUnit.SECONDS)
            .send();
    Assert.assertEquals(200, response.getStatus());
    Assert.assertTrue(response.getHeaders().containsKey(PROXIED_HEADER));
  }
  @Test
  public void testProxyWithBigRequestContentConsumed() throws Exception {
    final byte[] content = new byte[128 * 1024];
    new Random().nextBytes(content);

    prepareProxy();
    prepareServer(
        new HttpServlet() {
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
            if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true");
            InputStream input = req.getInputStream();
            int index = 0;
            while (true) {
              int value = input.read();
              if (value < 0) break;
              Assert.assertEquals(
                  "Content mismatch at index=" + index, content[index] & 0xFF, value);
              ++index;
            }
          }
        });

    ContentResponse response =
        client
            .newRequest("localhost", serverConnector.getLocalPort())
            .method(HttpMethod.POST)
            .content(new BytesContentProvider(content))
            .timeout(5, TimeUnit.SECONDS)
            .send();

    Assert.assertEquals(200, response.getStatus());
    Assert.assertTrue(response.getHeaders().containsKey(PROXIED_HEADER));
  }
  @Test
  public void testGZIPContentIsProxied() throws Exception {
    final byte[] content = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    prepareProxy();
    prepareServer(
        new HttpServlet() {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
            if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true");

            resp.addHeader("Content-Encoding", "gzip");
            GZIPOutputStream gzipOutputStream = new GZIPOutputStream(resp.getOutputStream());
            gzipOutputStream.write(content);
            gzipOutputStream.close();
          }
        });

    ContentResponse response =
        client
            .newRequest("localhost", serverConnector.getLocalPort())
            .timeout(5, TimeUnit.SECONDS)
            .send();
    Assert.assertEquals(200, response.getStatus());
    Assert.assertTrue(response.getHeaders().containsKey(PROXIED_HEADER));
    Assert.assertArrayEquals(content, response.getContent());
  }
示例#4
0
  protected String doContentRequest(
      String wsPart,
      String content,
      int expectedResponse,
      String expectedContent,
      HttpMethod method) {
    try {

      final ContentResponse contentResponse = doRequest(wsPart, method, content);

      System.err.println(content);

      dumpError(expectedResponse, contentResponse);

      Assert.assertEquals(expectedResponse, contentResponse.getStatus());

      if (expectedResponse == 500) {
        // no content available anyway
        return ""; //$NON-NLS-1$
      }
      final String retContent = contentResponse.getContentAsString();
      System.err.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>");
      System.err.println(retContent);

      if (expectedContent != null && retContent.indexOf(expectedContent) == -1) {
        System.err.println(retContent);
        Assert.fail();
      }
      return retContent;
    } catch (final Exception e) {
      throw new IllegalStateException(e);
    }
  }
  @Test
  public void testProxyWithRequestContentAndResponseContent() throws Exception {
    prepareProxy();
    prepareServer(
        new HttpServlet() {
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
            if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true");
            IO.copy(req.getInputStream(), resp.getOutputStream());
          }
        });

    byte[] content = new byte[1024];
    new Random().nextBytes(content);
    ContentResponse response =
        client
            .newRequest("localhost", serverConnector.getLocalPort())
            .method(HttpMethod.POST)
            .content(new BytesContentProvider(content))
            .timeout(5, TimeUnit.SECONDS)
            .send();

    Assert.assertEquals(200, response.getStatus());
    Assert.assertTrue(response.getHeaders().containsKey(PROXIED_HEADER));
    Assert.assertArrayEquals(content, response.getContent());
  }
  @Test
  public void testResponseHeadersAreNotRemoved() throws Exception {
    prepareProxy();
    proxyContext.stop();
    final String headerName = "X-Test";
    final String headerValue = "test-value";
    proxyContext.addFilter(
        new FilterHolder(
            new Filter() {
              @Override
              public void init(FilterConfig filterConfig) throws ServletException {}

              @Override
              public void doFilter(
                  ServletRequest request, ServletResponse response, FilterChain chain)
                  throws IOException, ServletException {
                ((HttpServletResponse) response).addHeader(headerName, headerValue);
                chain.doFilter(request, response);
              }

              @Override
              public void destroy() {}
            }),
        "/*",
        EnumSet.of(DispatcherType.REQUEST));
    proxyContext.start();
    prepareServer(new EmptyHttpServlet());

    HttpClient client = prepareClient();
    ContentResponse response =
        client.newRequest("localhost", serverConnector.getLocalPort()).send();

    Assert.assertEquals(200, response.getStatus());
    Assert.assertEquals(headerValue, response.getHeaders().get(headerName));
  }
  @Test
  public void createsMetricsForTheHandler() throws Exception {
    final ContentResponse response =
        client.GET("http://localhost:" + connector.getLocalPort() + "/hello");

    assertThat(response.getStatus()).isEqualTo(404);

    assertThat(registry.getNames())
        .containsOnly(
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.1xx-responses",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.2xx-responses",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.3xx-responses",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.4xx-responses",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.5xx-responses",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.active-suspended",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.async-dispatches",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.async-timeouts",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.get-requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.put-requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.active-dispatches",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.trace-requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.other-requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.connect-requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.dispatches",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.head-requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.post-requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.options-requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.active-requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.delete-requests",
            "org.eclipse.jetty.server.handler.DefaultHandler.handler.move-requests");
  }
  @Test
  public void testClientExcludedHosts() throws Exception {
    prepareProxy();
    prepareServer(
        new HttpServlet() {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
            if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true");
          }
        });
    int port = serverConnector.getLocalPort();
    client
        .getProxyConfiguration()
        .getProxies()
        .get(0)
        .getExcludedAddresses()
        .add("127.0.0.1:" + port);

    // Try with a proxied host
    ContentResponse response =
        client.newRequest("localhost", port).timeout(5, TimeUnit.SECONDS).send();
    Assert.assertEquals(200, response.getStatus());
    Assert.assertTrue(response.getHeaders().containsKey(PROXIED_HEADER));

    // Try again with an excluded host
    response = client.newRequest("127.0.0.1", port).timeout(5, TimeUnit.SECONDS).send();
    Assert.assertEquals(200, response.getStatus());
    Assert.assertFalse(response.getHeaders().containsKey(PROXIED_HEADER));
  }
示例#9
0
  @Override
  public ClientResponse apply(final ClientRequest jerseyRequest) throws ProcessingException {
    final Request jettyRequest = translateRequest(jerseyRequest);
    final Map<String, String> clientHeadersSnapshot =
        writeOutBoundHeaders(jerseyRequest.getHeaders(), jettyRequest);
    final ContentProvider entity = getBytesProvider(jerseyRequest);
    if (entity != null) {
      jettyRequest.content(entity);
    }

    try {
      final ContentResponse jettyResponse = jettyRequest.send();
      HeaderUtils.checkHeaderChanges(
          clientHeadersSnapshot,
          jerseyRequest.getHeaders(),
          JettyConnector.this.getClass().getName());

      final javax.ws.rs.core.Response.StatusType status =
          jettyResponse.getReason() == null
              ? Statuses.from(jettyResponse.getStatus())
              : Statuses.from(jettyResponse.getStatus(), jettyResponse.getReason());

      final ClientResponse jerseyResponse = new ClientResponse(status, jerseyRequest);
      processResponseHeaders(jettyResponse.getHeaders(), jerseyResponse);
      try {
        jerseyResponse.setEntityStream(new HttpClientResponseInputStream(jettyResponse));
      } catch (final IOException e) {
        LOGGER.log(Level.SEVERE, null, e);
      }

      return jerseyResponse;
    } catch (final Exception e) {
      throw new ProcessingException(e);
    }
  }
 protected byte[] sendRequestToBalancer(String path) throws Exception {
   ContentResponse response =
       client
           .newRequest("localhost", getServerPort(balancer))
           .path(CONTEXT_PATH + SERVLET_PATH + path)
           .send()
           .get(5, TimeUnit.SECONDS);
   return response.getContent();
 }
示例#11
0
 protected void doDeleteRequest(String wsPart, int expectedResponse) {
   try {
     final ContentResponse response = doRequest(wsPart, HttpMethod.DELETE, null);
     System.err.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>");
     System.err.println(response.getContent());
     Assert.assertEquals(expectedResponse, response.getStatus());
   } catch (final Exception e) {
     throw new IllegalStateException(e);
   }
 }
示例#12
0
 private void dumpError(int expectedResponseCode, ContentResponse response) throws Exception {
   if (expectedResponseCode != response.getStatus()
       && response.getStatus() == HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
     final String content = response.getContentAsString();
     if (content.contains("response:error")) { // $NON-NLS-1$
       final ErrorType errorType = (ErrorType) deserialize(content).get(0);
       System.err.println(errorType.getMessage());
       System.err.println(errorType.getStackTrace());
     }
   }
 }
  /**
   * If nodeA creates a session, and just afterwards crashes, it is the only node that knows about
   * the session. We want to test that the session data is gone after scavenging.
   */
  @Test
  public void testOrphanedSession() throws Exception {
    // Disable scavenging for the first server, so that we simulate its "crash".
    String contextPath = "";
    String servletMapping = "/server";
    int inactivePeriod = 5;
    AbstractTestServer server1 = createServer(0, inactivePeriod, -1);
    server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
    try {
      server1.start();
      int port1 = server1.getPort();
      int scavengePeriod = 2;
      AbstractTestServer server2 = createServer(0, inactivePeriod, scavengePeriod);
      server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
      try {
        server2.start();
        int port2 = server2.getPort();
        HttpClient client = new HttpClient();
        client.start();
        try {
          // Connect to server1 to create a session and get its session cookie
          ContentResponse response1 =
              client.GET(
                  "http://localhost:" + port1 + contextPath + servletMapping + "?action=init");
          assertEquals(HttpServletResponse.SC_OK, response1.getStatus());
          String sessionCookie = response1.getHeaders().getStringField("Set-Cookie");
          assertTrue(sessionCookie != null);
          // Mangle the cookie, replacing Path with $Path, etc.
          sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");

          // Wait for the session to expire.
          // The first node does not do any scavenging, but the session
          // must be removed by scavenging done in the other node.
          Thread.sleep(TimeUnit.SECONDS.toMillis(inactivePeriod + 2L * scavengePeriod));

          // Perform one request to server2 to be sure that the session has been expired
          Request request =
              client.newRequest(
                  "http://localhost:" + port2 + contextPath + servletMapping + "?action=check");
          request.header("Cookie", sessionCookie);
          ContentResponse response2 = request.send();
          assertEquals(HttpServletResponse.SC_OK, response2.getStatus());
        } finally {
          client.stop();
        }
      } finally {
        server2.stop();
      }
    } finally {
      server1.stop();
    }
  }
  @Test
  public void test_BasicAuthentication_ThenRedirect() throws Exception {
    startBasic(
        new AbstractHandler() {
          private final AtomicInteger requests = new AtomicInteger();

          @Override
          public void handle(
              String target,
              org.eclipse.jetty.server.Request baseRequest,
              HttpServletRequest request,
              HttpServletResponse response)
              throws IOException, ServletException {
            baseRequest.setHandled(true);
            if (requests.incrementAndGet() == 1)
              response.sendRedirect(
                  scheme
                      + "://"
                      + request.getServerName()
                      + ":"
                      + request.getServerPort()
                      + request.getRequestURI());
          }
        });

    URI uri = URI.create(scheme + "://localhost:" + connector.getLocalPort());
    client
        .getAuthenticationStore()
        .addAuthentication(new BasicAuthentication(uri, realm, "basic", "basic"));

    final CountDownLatch requests = new CountDownLatch(3);
    Request.Listener.Empty requestListener =
        new Request.Listener.Empty() {
          @Override
          public void onSuccess(Request request) {
            requests.countDown();
          }
        };
    client.getRequestListeners().add(requestListener);

    ContentResponse response =
        client
            .newRequest("localhost", connector.getLocalPort())
            .scheme(scheme)
            .path("/secure")
            .timeout(5, TimeUnit.SECONDS)
            .send();
    Assert.assertNotNull(response);
    Assert.assertEquals(200, response.getStatus());
    Assert.assertTrue(requests.await(5, TimeUnit.SECONDS));
    client.getRequestListeners().remove(requestListener);
  }
示例#15
0
  public void deleteRule(long id)
      throws InterruptedException, TimeoutException, ExecutionException {
    final ContentResponse response =
        newRequest()
            .path(CRITERIA_PATH)
            .method(HttpMethod.DELETE)
            .param("id", Long.toString(id))
            .send();

    if (response.getStatus() != 200) {
      throw new IllegalStateException("HTTP status code = " + response.getStatus());
    }
  }
  @Test
  @Ignore("failing because an http cookie with null value is coming over as \"null\"")
  public void testSessionCookie() throws Exception {
    String contextPath = "";
    String servletMapping = "/server";
    int scavengePeriod = 3;
    AbstractTestServer server = createServer(0, 1, scavengePeriod);
    ServletContextHandler context = server.addContext(contextPath);
    context.addServlet(TestServlet.class, servletMapping);

    try {
      server.start();
      int port = server.getPort();

      HttpClient client = new HttpClient();
      client.start();
      try {

        ContentResponse response =
            client.GET(
                "http://localhost:" + port + contextPath + servletMapping + "?action=create");
        assertEquals(HttpServletResponse.SC_OK, response.getStatus());

        String sessionCookie = response.getHeaders().get("Set-Cookie");
        assertTrue(sessionCookie != null);
        // Mangle the cookie, replacing Path with $Path, etc.
        // sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");

        // Let's wait for the scavenger to run, waiting 2.5 times the scavenger period
        // pause(scavengePeriod);
        Request request =
            client.newRequest(
                "http://localhost:" + port + contextPath + servletMapping + "?action=check-cookie");
        request.header("Cookie", sessionCookie);
        response = request.send();

        assertEquals(HttpServletResponse.SC_OK, response.getStatus());

        request =
            client.newRequest(
                "http://localhost:" + port + contextPath + servletMapping + "?action=null-cookie");
        request.header("Cookie", sessionCookie);
        response = request.send();
        assertEquals(HttpServletResponse.SC_OK, response.getStatus());
      } finally {
        client.stop();
      }
    } finally {
      server.stop();
    }
  }
示例#17
0
 @Override
 public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {
   try {
     final Request request = buildRequest(cr);
     writeOutBoundHeaders(cr.getHeaders(), request);
     final ContentResponse response = request.send();
     return new ClientResponse(
         response.getStatus(),
         getInBoundHeaders(response),
         new ByteArrayInputStream(response.getContent()),
         getMessageBodyWorkers());
   } catch (InterruptedException | TimeoutException | ExecutionException | IOException e) {
     throw new ClientHandlerException(e);
   }
 }
  @Test
  public void testConcurrentHandshakeFailureAndPublish() throws Exception {
    bayeux.setSecurityPolicy(new Policy());

    final String channelName = "/foo";
    final AtomicBoolean publish = new AtomicBoolean();
    new BroadcastChannelService(bayeux, channelName, publish);

    // A bad sequence of messages that clients should prevent
    // (by not allowing a publish until the handshake is completed)
    // yet the server must behave properly
    Request handshake =
        newBayeuxRequest(
            "[{"
                + "\"channel\": \"/meta/handshake\","
                + "\"version\": \"1.0\","
                + "\"minimumVersion\": \"1.0\","
                + "\"supportedConnectionTypes\": [\"long-polling\"]"
                + "}, {"
                + "\"clientId\": null,"
                + "\"channel\": \""
                + channelName
                + "\","
                + "\"data\": {}"
                + "}]");
    ContentResponse response = handshake.send();
    Assert.assertEquals(200, response.getStatus());

    JSONContext.Client jsonContext = new JettyJSONContextClient();
    Message.Mutable[] messages = jsonContext.parse(response.getContentAsString());
    Assert.assertEquals(2, messages.length);
    Message handshakeResponse = messages[0];
    Assert.assertFalse(handshakeResponse.isSuccessful());
    String handshakeError = (String) handshakeResponse.get("error");
    Assert.assertNotNull(handshakeError);
    Assert.assertTrue(handshakeError.contains("403"));
    Map<String, Object> advice = handshakeResponse.getAdvice();
    Assert.assertNotNull(advice);
    Assert.assertEquals(Message.RECONNECT_NONE_VALUE, advice.get("reconnect"));
    Message publishResponse = messages[1];
    Assert.assertFalse(publishResponse.isSuccessful());
    String publishError = (String) publishResponse.get("error");
    Assert.assertNotNull(publishError);
    Assert.assertTrue(publishError.contains("402"));
    Assert.assertNull(publishResponse.getAdvice());

    Assert.assertFalse(publish.get());
  }
  @Test
  public void test_BasicAuthentication_WithAuthenticationRemoved() throws Exception {
    startBasic(new EmptyServerHandler());

    final AtomicReference<CountDownLatch> requests = new AtomicReference<>(new CountDownLatch(2));
    Request.Listener.Empty requestListener =
        new Request.Listener.Empty() {
          @Override
          public void onSuccess(Request request) {
            requests.get().countDown();
          }
        };
    client.getRequestListeners().add(requestListener);

    AuthenticationStore authenticationStore = client.getAuthenticationStore();
    URI uri = URI.create(scheme + "://localhost:" + connector.getLocalPort());
    BasicAuthentication authentication = new BasicAuthentication(uri, realm, "basic", "basic");
    authenticationStore.addAuthentication(authentication);

    Request request =
        client.newRequest("localhost", connector.getLocalPort()).scheme(scheme).path("/secure");
    ContentResponse response = request.timeout(5, TimeUnit.SECONDS).send();
    Assert.assertNotNull(response);
    Assert.assertEquals(200, response.getStatus());
    Assert.assertTrue(requests.get().await(5, TimeUnit.SECONDS));

    authenticationStore.removeAuthentication(authentication);

    requests.set(new CountDownLatch(1));
    request =
        client.newRequest("localhost", connector.getLocalPort()).scheme(scheme).path("/secure");
    response = request.timeout(5, TimeUnit.SECONDS).send();
    Assert.assertNotNull(response);
    Assert.assertEquals(200, response.getStatus());
    Assert.assertTrue(requests.get().await(5, TimeUnit.SECONDS));

    Authentication.Result result = authenticationStore.findAuthenticationResult(request.getURI());
    Assert.assertNotNull(result);
    authenticationStore.removeAuthenticationResult(result);

    requests.set(new CountDownLatch(1));
    request =
        client.newRequest("localhost", connector.getLocalPort()).scheme(scheme).path("/secure");
    response = request.timeout(5, TimeUnit.SECONDS).send();
    Assert.assertNotNull(response);
    Assert.assertEquals(401, response.getStatus());
    Assert.assertTrue(requests.get().await(5, TimeUnit.SECONDS));
  }
  @Test
  public void testProxyBlackList() throws Exception {
    prepareProxy();
    prepareServer(new EmptyHttpServlet());
    int port = serverConnector.getLocalPort();
    proxyServlet.getBlackListHosts().add("localhost:" + port);

    // Try with the wrong host
    ContentResponse response =
        client.newRequest("localhost", port).timeout(5, TimeUnit.SECONDS).send();
    Assert.assertEquals(403, response.getStatus());

    // Try again with the right host
    response = client.newRequest("127.0.0.1", port).timeout(5, TimeUnit.SECONDS).send();
    Assert.assertEquals(200, response.getStatus());
  }
  @Test
  public void test_Expect100Continue_WithChunkedContent_Respond100Continue() throws Exception {
    start(
        new AbstractHandler() {
          @Override
          public void handle(
              String target,
              Request baseRequest,
              HttpServletRequest request,
              HttpServletResponse response)
              throws IOException, ServletException {
            baseRequest.setHandled(true);
            // Send 100-Continue and copy the content back
            ServletInputStream input = request.getInputStream();
            // Make sure we chunk the response too
            response.flushBuffer();
            IO.copy(input, response.getOutputStream());
          }
        });

    byte[] content1 = new byte[10240];
    byte[] content2 = new byte[16384];
    ContentResponse response =
        client
            .newRequest("localhost", connector.getLocalPort())
            .scheme(scheme)
            .header(HttpHeader.EXPECT.asString(), HttpHeaderValue.CONTINUE.asString())
            .content(
                new BytesContentProvider(content1, content2) {
                  @Override
                  public long getLength() {
                    return -1;
                  }
                })
            .send()
            .get(5, TimeUnit.SECONDS);

    Assert.assertNotNull(response);
    Assert.assertEquals(200, response.getStatus());

    int index = 0;
    byte[] responseContent = response.getContent();
    for (byte b : content1) Assert.assertEquals(b, responseContent[index++]);
    for (byte b : content2) Assert.assertEquals(b, responseContent[index++]);
  }
示例#22
0
  protected String doGetRequest(String wsPart, String testContent, int responseCode) {
    try {
      final ContentResponse contentResponse = doRequest(wsPart, HttpMethod.GET, null);
      dumpError(responseCode, contentResponse);
      final String content = contentResponse.getContentAsString();
      System.err.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>");

      System.err.println(content);

      Assert.assertEquals(responseCode, contentResponse.getStatus());
      if (testContent != null && content.indexOf(testContent) == -1) {
        System.err.println(content);
        Assert.fail();
      }
      return content;
    } catch (final Exception e) {
      throw new IllegalStateException("Exception when executing ws: " + wsPart, e); // $NON-NLS-1$
    }
  }
  @Test
  public void testProxyXForwardedHostHeaderIsPresent() throws Exception {
    prepareProxy();
    prepareServer(
        new HttpServlet() {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
            PrintWriter writer = resp.getWriter();
            writer.write(req.getHeader("X-Forwarded-Host"));
            writer.flush();
          }
        });

    ContentResponse response = client.GET("http://localhost:" + serverConnector.getLocalPort());
    Assert.assertThat(
        "Response expected to contain content of X-Forwarded-Host Header from the request",
        response.getContentAsString(),
        Matchers.equalTo("localhost:" + serverConnector.getLocalPort()));
  }
  @Test
  public void testProxyWithQueryString() throws Exception {
    prepareProxy();
    String query = "a=1&b=%E2%82%AC";
    prepareServer(
        new HttpServlet() {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
            resp.getOutputStream().print(req.getQueryString());
          }
        });

    ContentResponse response =
        client
            .newRequest("http://localhost:" + serverConnector.getLocalPort() + "/?" + query)
            .timeout(5, TimeUnit.SECONDS)
            .send();
    Assert.assertEquals(200, response.getStatus());
    Assert.assertEquals(query, response.getContentAsString());
  }
  @Test
  public void testProxyWithoutContent() throws Exception {
    prepareProxy();
    prepareServer(
        new HttpServlet() {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
            if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true");
          }
        });

    ContentResponse response =
        client
            .newRequest("localhost", serverConnector.getLocalPort())
            .timeout(5, TimeUnit.SECONDS)
            .send();

    Assert.assertEquals("OK", response.getReason());
    Assert.assertEquals(200, response.getStatus());
    Assert.assertTrue(response.getHeaders().containsKey(PROXIED_HEADER));
  }
  @Test
  public void testTransparentProxyWithQueryWithSpaces() throws Exception {
    final String target = "/test";
    final String query = "a=1&b=2&c=1234%205678&d=hello+world";
    prepareServer(
        new HttpServlet() {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
            if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true");

            if (target.equals(req.getRequestURI())) {
              if (query.equals(req.getQueryString())) {
                resp.setStatus(200);
                return;
              }
            }
            resp.setStatus(404);
          }
        });

    String proxyTo = "http://localhost:" + serverConnector.getLocalPort();
    String prefix = "/proxy";
    proxyServlet = new ProxyServlet.Transparent();
    Map<String, String> params = new HashMap<>();
    params.put("proxyTo", proxyTo);
    params.put("prefix", prefix);
    prepareProxy(params);

    // Make the request to the proxy, it should transparently forward to the server
    ContentResponse response =
        client
            .newRequest("localhost", proxyConnector.getLocalPort())
            .path(prefix + target + "?" + query)
            .timeout(5, TimeUnit.SECONDS)
            .send();
    Assert.assertEquals(200, response.getStatus());
    Assert.assertTrue(response.getHeaders().containsKey(PROXIED_HEADER));
  }
  @Test
  public void testSessionMigration() throws Exception {
    String contextPath = "";
    String servletMapping = "/server";
    AbstractTestServer server1 = createServer(0);
    server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);

    try {
      server1.start();
      int port1 = server1.getPort();

      AbstractTestServer server2 = createServer(0);
      server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping);

      try {
        server2.start();
        int port2 = server2.getPort();

        HttpClient client = new HttpClient();
        client.start();
        try {
          // Perform one request to server1 to create a session
          int value = 1;
          Request request1 =
              client.POST(
                  "http://localhost:"
                      + port1
                      + contextPath
                      + servletMapping
                      + "?action=set&value="
                      + value);
          ContentResponse response1 = request1.send();
          assertEquals(HttpServletResponse.SC_OK, response1.getStatus());
          String sessionCookie = response1.getHeaders().get("Set-Cookie");
          assertTrue(sessionCookie != null);
          // Mangle the cookie, replacing Path with $Path, etc.
          sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");

          // Perform a request to server2 using the session cookie from the previous request
          // This should migrate the session from server1 to server2.
          Request request2 =
              client.newRequest(
                  "http://localhost:" + port2 + contextPath + servletMapping + "?action=get");
          request2.header("Cookie", sessionCookie);
          ContentResponse response2 = request2.send();
          assertEquals(HttpServletResponse.SC_OK, response2.getStatus());
          String response = response2.getContentAsString();
          assertEquals(response.trim(), String.valueOf(value));
        } finally {
          client.stop();
        }
      } finally {
        server2.stop();
      }
    } finally {
      server1.stop();
    }
  }
  @Test
  public void testJspDump() throws Exception {

    // System.err.println("http://127.0.0.1:9876/jsp/dump.jsp  sleeping....");
    // Thread.currentThread().sleep(5000000);
    // now test the jsp/dump.jsp
    HttpClient client = new HttpClient();
    try {
      client.start();
      ContentResponse response =
          client.GET(
              "http://127.0.0.1:"
                  + TestJettyOSGiBootCore.DEFAULT_JETTY_HTTP_PORT
                  + "/jsp/dump.jsp");
      Assert.assertEquals(HttpStatus.OK_200, response.getStatus());

      String content = new String(response.getContent());
      System.err.println("content: " + content);
      Assert.assertTrue(content.contains("<tr><th>ServletPath:</th><td>/jsp/dump.jsp</td></tr>"));
    } finally {
      client.stop();
    }
  }
  @Test
  public void testAttributeNamesWithDots() throws Exception {
    String contextPath = "";
    String servletMapping = "/server";
    int maxInactivePeriod = 10000;
    int scavengePeriod = 20000;
    AbstractTestServer server1 = createServer(0, maxInactivePeriod, scavengePeriod);
    server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
    server1.start();
    int port1 = server1.getPort();

    AbstractTestServer server2 = createServer(0, maxInactivePeriod, scavengePeriod);
    server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
    server2.start();
    int port2 = server2.getPort();

    try {

      HttpClient client = new HttpClient();
      client.start();
      try {

        // Perform one request to server1 to create a session with attribute with dotted name
        ContentResponse response =
            client.GET("http://localhost:" + port1 + contextPath + servletMapping + "?action=init");

        assertEquals(HttpServletResponse.SC_OK, response.getStatus());

        String resp = response.getContentAsString();

        String[] sessionTestResponse = resp.split("/");
        assertEquals("a.b.c", sessionTestResponse[0]);

        String sessionCookie = response.getHeaders().get(HttpHeader.SET_COOKIE);

        assertTrue(sessionCookie != null);
        // Mangle the cookie, replacing Path with $Path, etc.
        sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");

        // Make a request to the 2nd server which will do a refresh, use TestServlet to ensure that
        // the
        // session attribute with dotted name is not removed
        Request request2 =
            client.newRequest(
                "http://localhost:" + port2 + contextPath + servletMapping + "?action=get");
        request2.header("Cookie", sessionCookie);
        ContentResponse response2 = request2.send();
        assertEquals(HttpServletResponse.SC_OK, response2.getStatus());

      } finally {
        client.stop();
      }
    } finally {
      server1.stop();
      server2.stop();
    }
  }
  private void test_Expect100Continue_Respond100Continue(byte[]... contents) throws Exception {
    start(
        new AbstractHandler() {
          @Override
          public void handle(
              String target,
              Request baseRequest,
              HttpServletRequest request,
              HttpServletResponse response)
              throws IOException, ServletException {
            baseRequest.setHandled(true);
            // Send 100-Continue and copy the content back
            IO.copy(request.getInputStream(), response.getOutputStream());
          }
        });

    ContentResponse response =
        client
            .newRequest("localhost", connector.getLocalPort())
            .scheme(scheme)
            .header(HttpHeader.EXPECT.asString(), HttpHeaderValue.CONTINUE.asString())
            .content(new BytesContentProvider(contents))
            .send()
            .get(5, TimeUnit.SECONDS);

    Assert.assertNotNull(response);
    Assert.assertEquals(200, response.getStatus());

    int index = 0;
    byte[] responseContent = response.getContent();
    for (byte[] content : contents) {
      for (byte b : content) {
        Assert.assertEquals(b, responseContent[index++]);
      }
    }
  }