@Before
  public void init() throws Exception {
    server = new Server();

    connector = new LocalConnector(server);
    connector
        .getConnectionFactory(HttpConfiguration.ConnectionFactory.class)
        .getHttpConfiguration()
        .setSendServerVersion(false);

    context = new ServletContextHandler();
    context.setContextPath("/context");
    context.setWelcomeFiles(new String[] {"index.html", "index.jsp", "index.htm"});

    server.setHandler(context);
    server.addConnector(connector);

    testdir.ensureEmpty();
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    File data = new File(resBase, "data.txt");
    createFile(data, DATA);
    String resBasePath = resBase.getAbsolutePath();

    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("acceptRanges", "true");
    defholder.setInitParameter("resourceBase", resBasePath);

    server.start();
  }
  @Test
  public void testGzip() throws Exception {
    testdir.ensureEmpty();
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    File file0 = new File(resBase, "data0.txt");
    createFile(file0, "Hello Text 0");
    File file0gz = new File(resBase, "data0.txt.gz");
    createFile(file0gz, "fake gzip");

    String resBasePath = resBase.getAbsolutePath();

    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("dirAllowed", "false");
    defholder.setInitParameter("redirectWelcome", "false");
    defholder.setInitParameter("welcomeServlets", "false");
    defholder.setInitParameter("gzip", "true");
    defholder.setInitParameter("resourceBase", resBasePath);

    String response =
        connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\n\r\n");
    assertResponseContains("Content-Length: 12", response);
    assertResponseContains("Hello Text 0", response);
    assertResponseContains("Vary: Accept-Encoding", response);
    assertResponseNotContains("Content-Encoding: gzip", response);

    response =
        connector.getResponses(
            "GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\n\r\n");
    assertResponseContains("Content-Length: 9", response);
    assertResponseContains("fake gzip", response);
    assertResponseContains("Vary: Accept-Encoding", response);
    assertResponseContains("Content-Encoding: gzip", response);
  }
  @Test
  public void testResourceBase() throws Exception {
    testdir.ensureEmpty();
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    File foobar = new File(resBase, "foobar.txt");
    File link = new File(resBase, "link.txt");
    createFile(foobar, "Foo Bar");

    String resBasePath = resBase.getAbsolutePath();

    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("resourceBase", resBasePath);
    defholder.setInitParameter("gzip", "false");

    String response;

    response = connector.getResponses("GET /context/foobar.txt HTTP/1.0\r\n\r\n");
    assertResponseContains("Foo Bar", response);

    if (!OS.IS_WINDOWS) {
      Files.createSymbolicLink(link.toPath(), foobar.toPath());
      response = connector.getResponses("GET /context/link.txt HTTP/1.0\r\n\r\n");
      assertResponseContains("404", response);

      context.addAliasCheck(new ContextHandler.ApproveAliases());

      response = connector.getResponses("GET /context/link.txt HTTP/1.0\r\n\r\n");
      assertResponseContains("Foo Bar", response);
    }
  }
  @Test
  public void testListingWithSession() throws Exception {
    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/*");
    defholder.setInitParameter("dirAllowed", "true");
    defholder.setInitParameter("redirectWelcome", "false");
    defholder.setInitParameter("gzip", "false");

    testdir.ensureEmpty();

    /* create some content in the docroot */
    File resBase = testdir.getFile("docroot");
    assertTrue(resBase.mkdirs());
    assertTrue(new File(resBase, "one").mkdir());
    assertTrue(new File(resBase, "two").mkdir());
    assertTrue(new File(resBase, "three").mkdir());

    String resBasePath = resBase.getAbsolutePath();
    defholder.setInitParameter("resourceBase", resBasePath);

    StringBuffer req1 = new StringBuffer();
    req1.append("GET /context/;JSESSIONID=1234567890 HTTP/1.0\n\n");

    String response = connector.getResponses(req1.toString());

    assertResponseContains("/one/;JSESSIONID=1234567890", response);
    assertResponseContains("/two/;JSESSIONID=1234567890", response);
    assertResponseContains("/three/;JSESSIONID=1234567890", response);

    assertResponseNotContains("<script>", response);
  }
  @Before
  public void setUp() throws Exception {
    HttpConfiguration http_config = new HttpConfiguration();
    http_config.setOutputBufferSize(4096);
    _connector = new ServerConnector(_server, new HttpConnectionFactory(http_config));

    _server.setConnectors(new Connector[] {_connector});
    ServletContextHandler context = new ServletContextHandler();
    context.setContextPath("/ctx");
    _server.setHandler(context);
    _servletHandler = context.getServletHandler();

    ServletHolder holder = new ServletHolder(_servlet0);
    holder.setAsyncSupported(true);
    _servletHandler.addServletWithMapping(holder, "/path/*");

    ServletHolder holder2 = new ServletHolder(_servlet2);
    holder.setAsyncSupported(true);
    _servletHandler.addServletWithMapping(holder2, "/path2/*");

    _server.start();
    _port = _connector.getLocalPort();

    _owp.set(0);
    _oda.set(0);
    _read.set(0);
  }
    @Override
    public ServletRegistration getServletRegistration(String servletName) {
      if (!_enabled) throw new UnsupportedOperationException();

      final ServletHolder holder =
          ServletContextHandler.this.getServletHandler().getServlet(servletName);
      return (holder == null) ? null : holder.getRegistration();
    }
 /*
  * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
  */
 @Override
 public RequestDispatcher getNamedDispatcher(String name) {
   ContextHandler context = org.eclipse.jetty.servlet.ServletContextHandler.this;
   if (_servletHandler == null) return null;
   ServletHolder holder = _servletHandler.getServlet(name);
   if (holder == null || !holder.isEnabled()) return null;
   return new Dispatcher(context, name);
 }
    @Override
    public Map<String, ? extends ServletRegistration> getServletRegistrations() {
      if (!_enabled) throw new UnsupportedOperationException();

      HashMap<String, ServletRegistration> registrations =
          new HashMap<String, ServletRegistration>();
      ServletHandler handler = ServletContextHandler.this.getServletHandler();
      ServletHolder[] holders = handler.getServlets();
      if (holders != null) {
        for (ServletHolder holder : holders)
          registrations.put(holder.getName(), holder.getRegistration());
      }
      return registrations;
    }
  @Test
  public void testListingProperUrlEncoding() throws Exception {
    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/*");
    defholder.setInitParameter("dirAllowed", "true");
    defholder.setInitParameter("redirectWelcome", "false");
    defholder.setInitParameter("gzip", "false");

    testdir.ensureEmpty();

    /* create some content in the docroot */
    File resBase = testdir.getFile("docroot");
    assertTrue(resBase.mkdirs());
    File wackyDir = new File(resBase, "dir;"); // this should not be double-encoded.
    assertTrue(wackyDir.mkdirs());

    assertTrue(new File(wackyDir, "four").mkdir());
    assertTrue(new File(wackyDir, "five").mkdir());
    assertTrue(new File(wackyDir, "six").mkdir());

    /* At this point we have the following
     * testListingProperUrlEncoding/
     * `-- docroot
     *     `-- dir;
     *         |-- five
     *         |-- four
     *         `-- six
     */

    String resBasePath = resBase.getAbsolutePath();
    defholder.setInitParameter("resourceBase", resBasePath);

    // First send request in improper, unencoded way.
    String response = connector.getResponses("GET /context/dir;/ HTTP/1.0\r\n\r\n");

    assertResponseContains("HTTP/1.1 404 Not Found", response);

    // Now send request in proper, encoded format.
    response = connector.getResponses("GET /context/dir%3B/ HTTP/1.0\r\n\r\n");

    // Should not see double-encoded ";"
    // First encoding: ";" -> "%3b"
    // Second encoding: "%3B" -> "%253B" (BAD!)
    assertResponseNotContains("%253B", response);

    assertResponseContains("/dir%3B/", response);
    assertResponseContains("/dir%3B/four/", response);
    assertResponseContains("/dir%3B/five/", response);
    assertResponseContains("/dir%3B/six/", response);
  }
  @Test
  public void testWelcomeExactServlet() throws Exception {
    testdir.ensureEmpty();
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    File inde = new File(resBase, "index.htm");
    File index = new File(resBase, "index.html");

    String resBasePath = resBase.getAbsolutePath();

    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("dirAllowed", "false");
    defholder.setInitParameter("redirectWelcome", "false");
    defholder.setInitParameter("welcomeServlets", "exact");
    defholder.setInitParameter("gzip", "false");
    defholder.setInitParameter("resourceBase", resBasePath);

    ServletHolder jspholder = context.addServlet(NoJspServlet.class, "*.jsp");
    context.addServlet(jspholder, "/index.jsp");

    String response;

    response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
    assertResponseContains("JSP support not configured", response);

    createFile(index, "<h1>Hello Index</h1>");
    response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
    assertResponseContains("<h1>Hello Index</h1>", response);

    createFile(inde, "<h1>Hello Inde</h1>");
    response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
    assertResponseContains("<h1>Hello Index</h1>", response);

    // In Windows it's impossible to delete files that are somehow in use
    // Avoid to fail the test if we're on Windows
    if (!OS.IS_WINDOWS) {
      deleteFile(index);
      response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
      assertResponseContains("<h1>Hello Inde</h1>", response);

      deleteFile(inde);
      response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
      assertResponseContains("JSP support not configured", response);
    }
  }
    /** @since servlet-api-3.0 */
    @Override
    public ServletRegistration.Dynamic addServlet(
        String servletName, Class<? extends Servlet> servletClass) {
      if (!isStarting()) throw new IllegalStateException();

      if (servletName == null || "".equals(servletName.trim()))
        throw new IllegalStateException("Missing servlet name");

      if (!_enabled) throw new UnsupportedOperationException();

      final ServletHandler handler = ServletContextHandler.this.getServletHandler();
      ServletHolder holder = handler.getServlet(servletName);
      if (holder == null) {
        // new servlet
        holder = handler.newServletHolder(Source.JAVAX_API);
        holder.setName(servletName);
        holder.setHeldClass(servletClass);
        handler.addServlet(holder);
        return dynamicHolderAdded(holder);
      }

      // complete a partial registration
      if (holder.getClassName() == null && holder.getHeldClass() == null) {
        holder.setHeldClass(servletClass);
        return holder.getRegistration();
      } else return null; // existing completed registration for servlet name
    }
  /* ------------------------------------------------------------ */
  public void sendError(int status, String message) throws IOException {
    // Find  error page.
    String error_page =
        _servletHttpRequest.getServletHandler().getErrorPage(status, _servletHttpRequest);

    resetBuffer();

    // Handle error page?
    if (error_page == null) {
      // handle normally
      _httpResponse.sendError(status, message);
    } else {
      _httpResponse.setStatus(status, message);

      if (message == null) {
        message = (String) HttpResponse.__statusMsg.get(TypeUtil.newInteger(status));
        if (message == null) message = "" + status;
      }

      // handle error page
      ServletHolder holder = _servletHttpRequest.getServletHolder();
      if (holder != null)
        _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_SERVLET_NAME, holder.getName());
      _servletHttpRequest.setAttribute(
          ServletHandler.__J_S_ERROR_REQUEST_URI, _servletHttpRequest.getRequestURI());
      _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_STATUS_CODE, new Integer(status));
      _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_MESSAGE, message);

      RequestDispatcher dispatcher =
          _servletHttpRequest
              .getServletHandler()
              .getServletContext()
              .getRequestDispatcher(error_page);

      try {
        ((Dispatcher) dispatcher).error(_servletHttpRequest, this);
      } catch (ServletException e) {
        log.warn(LogSupport.EXCEPTION, e);
        _httpResponse.sendError(status, message);
      }
    }
    complete();
  }
  @Test
  public void testListingXSS() throws Exception {
    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/*");
    defholder.setInitParameter("dirAllowed", "true");
    defholder.setInitParameter("redirectWelcome", "false");
    defholder.setInitParameter("gzip", "false");

    testdir.ensureEmpty();

    /* create some content in the docroot */
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    assertTrue(new File(resBase, "one").mkdir());
    assertTrue(new File(resBase, "two").mkdir());
    assertTrue(new File(resBase, "three").mkdir());
    if (!OS.IS_WINDOWS) {
      assertTrue(
          "Creating dir 'f??r' (Might not work in Windows)", new File(resBase, "f??r").mkdir());
    }

    String resBasePath = resBase.getAbsolutePath();
    defholder.setInitParameter("resourceBase", resBasePath);

    StringBuffer req1 = new StringBuffer();
    /*
     * Intentionally bad request URI. Sending a non-encoded URI with typically encoded characters '<', '>', and
     * '"'.
     */
    req1.append("GET /context/;<script>window.alert(\"hi\");</script> HTTP/1.0\n");
    req1.append("\n");

    String response = connector.getResponses(req1.toString());

    assertResponseContains("/one/", response);
    assertResponseContains("/two/", response);
    assertResponseContains("/three/", response);
    if (!OS.IS_WINDOWS) {
      assertResponseContains("/f%3F%3Fr", response);
    }

    assertResponseNotContains("<script>", response);
  }
  public static void main(String[] args) {
    Server server = new Server(9001);
    ServletContextHandler contextHandler =
        new ServletContextHandler(ServletContextHandler.SESSIONS);

    contextHandler.setContextPath("/");

    ServletHolder holder = new ServletHolder(new ServletContainer());

    holder.setInitParameter("javax.ws.rs.Application", "backtobasic.rest.div.Services");
    contextHandler.addServlet(holder, "/*");
    server.setHandler(contextHandler);

    try {
      server.start();
      server.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
示例#15
0
  @Test
  public void testInitParams() throws Exception {
    ServletHolder holder = new ServletHolder(Source.JAVAX_API);
    ServletRegistration reg = holder.getRegistration();
    try {
      reg.setInitParameter(null, "foo");
      fail("null name accepted");
    } catch (IllegalArgumentException e) {
    }
    try {
      reg.setInitParameter("foo", null);
      fail("null value accepted");
    } catch (IllegalArgumentException e) {
    }
    reg.setInitParameter("foo", "bar");
    assertFalse(reg.setInitParameter("foo", "foo"));

    Set<String> clash = reg.setInitParameters(Collections.singletonMap("foo", "bax"));
    assertTrue("should be one clash", clash != null && clash.size() == 1);

    try {
      reg.setInitParameters(Collections.singletonMap((String) null, "bax"));
      fail("null name in map accepted");
    } catch (IllegalArgumentException e) {
    }
    try {
      reg.setInitParameters(Collections.singletonMap("foo", (String) null));
      fail("null value in map accepted");
    } catch (IllegalArgumentException e) {
    }

    Set<String> clash2 = reg.setInitParameters(Collections.singletonMap("FOO", "bax"));
    assertTrue("should be no clash", clash2.isEmpty());
    assertEquals(
        "setInitParameters should not replace existing non-clashing init parameters",
        2,
        reg.getInitParameters().size());
  }
  @Test
  public void testInitOrder() throws Exception {
    ServletContextHandler context = new ServletContextHandler();
    ServletHolder holder0 = context.addServlet(TestServlet.class, "/test0");
    ServletHolder holder1 = context.addServlet(TestServlet.class, "/test1");
    ServletHolder holder2 = context.addServlet(TestServlet.class, "/test2");

    holder1.setInitOrder(1);
    holder2.setInitOrder(2);

    context.setContextPath("/");
    _server.setHandler(context);
    _server.start();

    assertEquals(2, __testServlets.get());

    String response = _connector.getResponses("GET /test1 HTTP/1.0\r\n\r\n");
    Assert.assertThat(response, Matchers.containsString("200 OK"));

    assertEquals(2, __testServlets.get());

    response = _connector.getResponses("GET /test2 HTTP/1.0\r\n\r\n");
    Assert.assertThat(response, containsString("200 OK"));

    assertEquals(2, __testServlets.get());

    assertThat(holder0.getServletInstance(), nullValue());
    response = _connector.getResponses("GET /test0 HTTP/1.0\r\n\r\n");
    assertThat(response, containsString("200 OK"));
    assertEquals(3, __testServlets.get());
    assertThat(holder0.getServletInstance(), notNullValue(Servlet.class));

    _server.stop();
    assertEquals(0, __testServlets.get());

    holder0.setInitOrder(0);
    _server.start();
    assertEquals(3, __testServlets.get());
    assertThat(holder0.getServletInstance(), notNullValue(Servlet.class));
    _server.stop();
    assertEquals(0, __testServlets.get());
  }
  @Test
  public void testFiltered() throws Exception {
    testdir.ensureEmpty();
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    File file0 = new File(resBase, "data0.txt");
    createFile(file0, "Hello Text 0");

    String resBasePath = resBase.getAbsolutePath();

    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("dirAllowed", "false");
    defholder.setInitParameter("redirectWelcome", "false");
    defholder.setInitParameter("welcomeServlets", "false");
    defholder.setInitParameter("gzip", "false");
    defholder.setInitParameter("resourceBase", resBasePath);

    String response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\n\r\n");
    assertResponseContains("Content-Length: 12", response);
    assertResponseNotContains("Extra Info", response);

    context.addFilter(OutputFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
    response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\n\r\n");
    assertResponseContains("Content-Length: 2", response); // 20 something long
    assertResponseContains("Extra Info", response);
    assertResponseNotContains("Content-Length: 12", response);

    context.getServletHandler().setFilterMappings(new FilterMapping[] {});
    context.getServletHandler().setFilters(new FilterHolder[] {});

    context.addFilter(WriterFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
    response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\n\r\n");
    assertResponseContains("Content-Length: 2", response); // 20 something long
    assertResponseContains("Extra Info", response);
    assertResponseNotContains("Content-Length: 12", response);
  }
  @Test
  public void testWelcome() throws Exception {
    testdir.ensureEmpty();
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    File inde = new File(resBase, "index.htm");
    File index = new File(resBase, "index.html");

    String resBasePath = resBase.getAbsolutePath();

    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("dirAllowed", "false");
    defholder.setInitParameter("redirectWelcome", "false");
    defholder.setInitParameter("welcomeServlets", "false");
    defholder.setInitParameter("gzip", "false");
    defholder.setInitParameter("resourceBase", resBasePath);
    defholder.setInitParameter("maxCacheSize", "1024000");
    defholder.setInitParameter("maxCachedFileSize", "512000");
    defholder.setInitParameter("maxCachedFiles", "100");

    @SuppressWarnings("unused")
    ServletHolder jspholder = context.addServlet(NoJspServlet.class, "*.jsp");

    String response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
    assertResponseContains("403", response);

    createFile(index, "<h1>Hello Index</h1>");
    response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
    assertResponseContains("<h1>Hello Index</h1>", response);

    createFile(inde, "<h1>Hello Inde</h1>");
    response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
    assertResponseContains("<h1>Hello Index</h1>", response);

    assertTrue(index.delete());
    response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
    assertResponseContains("<h1>Hello Inde</h1>", response);

    assertTrue(inde.delete());
    response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
    assertResponseContains("403", response);
  }
  @Test
  public void testListingContextBreakout() throws Exception {
    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("dirAllowed", "true");
    defholder.setInitParameter("redirectWelcome", "false");
    defholder.setInitParameter("gzip", "false");
    defholder.setInitParameter("aliases", "true");

    testdir.ensureEmpty();

    /* create some content in the docroot */
    File resBase = testdir.getFile("docroot");
    assertTrue(resBase.mkdirs());

    File index = new File(resBase, "index.html");
    createFile(index, "<h1>Hello Index</h1>");

    File wackyDir = new File(resBase, "dir?");
    if (!OS.IS_WINDOWS) {
      FS.ensureDirExists(wackyDir);
    }

    wackyDir = new File(resBase, "dir;");
    assertTrue(wackyDir.mkdirs());

    /* create some content outside of the docroot */
    File sekret = testdir.getFile("sekret");
    assertTrue(sekret.mkdirs());
    File pass = new File(sekret, "pass");
    createFile(pass, "Sssh, you shouldn't be seeing this");

    /* At this point we have the following
     * testListingContextBreakout/
     * |-- docroot
     * |   |-- index.html
     * |   |-- dir?
     * |   |-- dir;
     * `-- sekret
     *     `-- pass
     */

    String resBasePath = resBase.getAbsolutePath();
    defholder.setInitParameter("resourceBase", resBasePath);

    String response;

    response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
    assertResponseContains("<h1>Hello Index</h1>", response);

    response = connector.getResponses("GET /context/dir?/ HTTP/1.0\r\n\r\n");
    assertResponseContains("404", response);

    if (!OS.IS_WINDOWS) {
      response = connector.getResponses("GET /context/dir%3F/ HTTP/1.0\r\n\r\n");
      assertResponseContains("Directory: /context/dir?/<", response);
    } else assertResponseContains("404", response);

    response = connector.getResponses("GET /context/index.html HTTP/1.0\r\n\r\n");
    assertResponseContains("Hello Index", response);

    response = connector.getResponses("GET /context/dir%3F/../index.html HTTP/1.0\r\n\r\n");
    assertResponseContains("Hello Index", response);

    response = connector.getResponses("GET /context/dir%3F/../../ HTTP/1.0\r\n\r\n");
    assertResponseNotContains("Directory: ", response);

    response = connector.getResponses("GET /context/dir%3F/../../sekret/pass HTTP/1.0\r\n\r\n");
    assertResponseNotContains("Sssh", response);

    response = connector.getResponses("GET /context/dir?/../../ HTTP/1.0\r\n\r\n");
    assertResponseNotContains("Directory: ", response);

    response = connector.getResponses("GET /context/dir?/../../sekret/pass HTTP/1.0\r\n\r\n");
    assertResponseNotContains("Sssh", response);

    response = connector.getResponses("GET /context/ HTTP/1.0\r\n\r\n");
    assertResponseContains("<h1>Hello Index</h1>", response);

    response = connector.getResponses("GET /context/dir;/ HTTP/1.0\r\n\r\n");
    assertResponseContains("404", response);

    response = connector.getResponses("GET /context/dir%3B/ HTTP/1.0\r\n\r\n");
    assertResponseContains("Directory: /context/dir;/<", response);

    response = connector.getResponses("GET /context/index.html HTTP/1.0\r\n\r\n");
    assertResponseContains("Hello Index", response);

    response = connector.getResponses("GET /context/dir%3B/../index.html HTTP/1.0\r\n\r\n");
    assertResponseContains("Hello Index", response);

    response = connector.getResponses("GET /context/dir%3B/../../ HTTP/1.0\r\n\r\n");
    assertResponseNotContains("Directory: ", response);

    response = connector.getResponses("GET /context/dir%3B/../../sekret/pass HTTP/1.0\r\n\r\n");
    assertResponseNotContains("Sssh", response);

    response = connector.getResponses("GET /context/dir;/../../ HTTP/1.0\r\n\r\n");
    assertResponseNotContains("Directory: ", response);

    response = connector.getResponses("GET /context/dir;/../../sekret/pass HTTP/1.0\r\n\r\n");
    assertResponseNotContains("Sssh", response);
  }
 /**
  * notification that a ServletRegistration has been created so we can track the annotations
  *
  * @param holder new holder created through the api.
  * @return the ServletRegistration.Dynamic
  */
 protected ServletRegistration.Dynamic dynamicHolderAdded(ServletHolder holder) {
   return holder.getRegistration();
 }
  @Test
  public void testRangeRequests() throws Exception {
    testdir.ensureEmpty();
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    File data = new File(resBase, "data.txt");
    createFile(
        data, "01234567890123456789012345678901234567890123456789012345678901234567890123456789");
    String resBasePath = resBase.getAbsolutePath();

    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("dirAllowed", "false");
    defholder.setInitParameter("redirectWelcome", "false");
    defholder.setInitParameter("welcomeServlets", "false");
    defholder.setInitParameter("gzip", "false");
    defholder.setInitParameter("acceptRanges", "true");
    defholder.setInitParameter("resourceBase", resBasePath);

    String response =
        connector.getResponses(
            "GET /context/data.txt HTTP/1.1\r\n"
                + "Host: localhost\r\n"
                + "Connection: close\r\n\r\n");
    assertResponseContains("200 OK", response);
    assertResponseContains("Accept-Ranges: bytes", response);

    response =
        connector.getResponses(
            "GET /context/data.txt HTTP/1.1\r\n"
                + "Host: localhost\r\n"
                + "Connection: close\r\n"
                + "Range: bytes=0-9\r\n"
                + "\r\n");
    assertResponseContains("206 Partial", response);
    assertResponseContains("Content-Type: text/plain", response);
    assertResponseContains("Content-Length: 10", response);
    assertResponseContains("Content-Range: bytes 0-9/80", response);

    response =
        connector.getResponses(
            "GET /context/data.txt HTTP/1.1\r\n"
                + "Host: localhost\r\n"
                + "Connection: close\r\n"
                + "Range: bytes=0-9,20-29,40-49\r\n"
                + "\r\n");
    int start = response.indexOf("--jetty");
    String body = response.substring(start);
    String boundary = body.substring(0, body.indexOf("\r\n"));
    assertResponseContains("206 Partial", response);
    assertResponseContains("Content-Type: multipart/byteranges; boundary=", response);
    assertResponseContains("Content-Range: bytes 0-9/80", response);
    assertResponseContains("Content-Range: bytes 20-29/80", response);
    assertResponseContains("Content-Length: " + body.length(), response);
    assertTrue(body.endsWith(boundary + "--\r\n"));

    response =
        connector.getResponses(
            "GET /context/data.txt HTTP/1.1\r\n"
                + "Host: localhost\r\n"
                + "Connection: close\r\n"
                + "Range: bytes=0-9,20-29,40-49,70-79\r\n"
                + "\r\n");
    start = response.indexOf("--jetty");
    body = response.substring(start);
    boundary = body.substring(0, body.indexOf("\r\n"));
    assertResponseContains("206 Partial", response);
    assertResponseContains("Content-Type: multipart/byteranges; boundary=", response);
    assertResponseContains("Content-Range: bytes 0-9/80", response);
    assertResponseContains("Content-Range: bytes 20-29/80", response);
    assertResponseContains("Content-Range: bytes 70-79/80", response);
    assertResponseContains("Content-Length: " + body.length(), response);
    assertTrue(body.endsWith(boundary + "--\r\n"));

    response =
        connector.getResponses(
            "GET /context/data.txt HTTP/1.1\r\n"
                + "Host: localhost\r\n"
                + "Connection: close\r\n"
                + "Range: bytes=0-9,20-29,40-49,60-60,70-79\r\n"
                + "\r\n");
    start = response.indexOf("--jetty");
    body = response.substring(start);
    boundary = body.substring(0, body.indexOf("\r\n"));
    assertResponseContains("206 Partial", response);
    assertResponseContains("Content-Type: multipart/byteranges; boundary=", response);
    assertResponseContains("Content-Range: bytes 0-9/80", response);
    assertResponseContains("Content-Range: bytes 20-29/80", response);
    assertResponseContains("Content-Range: bytes 60-60/80", response);
    assertResponseContains("Content-Range: bytes 70-79/80", response);
    assertResponseContains("Content-Length: " + body.length(), response);
    assertTrue(body.endsWith(boundary + "--\r\n"));

    // test a range request with a file with no suffix, therefore no mimetype

    File nofilesuffix = new File(resBase, "nofilesuffix");
    createFile(
        nofilesuffix,
        "01234567890123456789012345678901234567890123456789012345678901234567890123456789");

    response =
        connector.getResponses(
            "GET /context/nofilesuffix HTTP/1.1\r\n"
                + "Host: localhost\r\n"
                + "Connection: close\r\n"
                + "\r\n");
    assertResponseContains("200 OK", response);
    assertResponseContains("Accept-Ranges: bytes", response);

    response =
        connector.getResponses(
            "GET /context/nofilesuffix HTTP/1.1\r\n"
                + "Host: localhost\r\n"
                + "Connection: close\r\n"
                + "Range: bytes=0-9\r\n"
                + "\r\n");
    assertResponseContains("206 Partial", response);
    assertResponseContains("Content-Length: 10", response);
    assertTrue(!response.contains("Content-Type:"));
    assertResponseContains("Content-Range: bytes 0-9/80", response);

    response =
        connector.getResponses(
            "GET /context/nofilesuffix HTTP/1.1\r\n"
                + "Host: localhost\r\n"
                + "Connection: close\r\n"
                + "Range: bytes=0-9,20-29,40-49\r\n"
                + "\r\n");
    start = response.indexOf("--jetty");
    body = response.substring(start);
    boundary = body.substring(0, body.indexOf("\r\n"));
    assertResponseContains("206 Partial", response);
    assertResponseContains("Content-Type: multipart/byteranges; boundary=", response);
    assertResponseContains("Content-Range: bytes 0-9/80", response);
    assertResponseContains("Content-Range: bytes 20-29/80", response);
    assertResponseContains("Content-Length: " + body.length(), response);
    assertTrue(body.endsWith(boundary + "--\r\n"));

    response =
        connector.getResponses(
            "GET /context/nofilesuffix HTTP/1.1\r\n"
                + "Host: localhost\r\n"
                + "Connection: close\r\n"
                + "Range: bytes=0-9,20-29,40-49,60-60,70-79\r\n"
                + "\r\n");
    start = response.indexOf("--jetty");
    body = response.substring(start);
    boundary = body.substring(0, body.indexOf("\r\n"));
    assertResponseContains("206 Partial", response);
    assertResponseContains("Content-Type: multipart/byteranges; boundary=", response);
    assertResponseContains("Content-Range: bytes 0-9/80", response);
    assertResponseContains("Content-Range: bytes 20-29/80", response);
    assertResponseContains("Content-Range: bytes 60-60/80", response);
    assertResponseContains("Content-Range: bytes 70-79/80", response);
    assertResponseContains("Content-Length: " + body.length(), response);
    assertTrue(body.endsWith(boundary + "--\r\n"));
  }
  public void testIfModified(String content) throws Exception {
    testdir.ensureEmpty();
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    File file = new File(resBase, "file.txt");

    String resBasePath = resBase.getAbsolutePath();

    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("resourceBase", resBasePath);
    defholder.setInitParameter("maxCacheSize", "4096");
    defholder.setInitParameter("maxCachedFileSize", "25");
    defholder.setInitParameter("maxCachedFiles", "100");

    String response = connector.getResponses("GET /context/file.txt HTTP/1.0\r\n\r\n");
    assertResponseContains("404", response);

    createFile(file, content);
    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\n\r\n");

    assertResponseContains("200", response);
    assertResponseContains("Last-Modified", response);
    String last_modified = getHeaderValue("Last-Modified", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-Modified-Since: "
                + last_modified
                + "\r\n\r\n");
    assertResponseContains("304", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-Modified-Since: "
                + HttpFields.formatDate(System.currentTimeMillis() - 10000)
                + "\r\n\r\n");
    assertResponseContains("200", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-Modified-Since: "
                + HttpFields.formatDate(System.currentTimeMillis() + 10000)
                + "\r\n\r\n");
    assertResponseContains("304", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-Unmodified-Since: "
                + HttpFields.formatDate(System.currentTimeMillis() + 10000)
                + "\r\n\r\n");
    assertResponseContains("200", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-Unmodified-Since: "
                + HttpFields.formatDate(System.currentTimeMillis() - 10000)
                + "\r\n\r\n");
    assertResponseContains("412", response);
  }
  public void testIfETag(String content) throws Exception {
    testdir.ensureEmpty();
    File resBase = testdir.getFile("docroot");
    FS.ensureDirExists(resBase);
    File file = new File(resBase, "file.txt");

    String resBasePath = resBase.getAbsolutePath();

    ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
    defholder.setInitParameter("resourceBase", resBasePath);
    defholder.setInitParameter("maxCacheSize", "4096");
    defholder.setInitParameter("maxCachedFileSize", "25");
    defholder.setInitParameter("maxCachedFiles", "100");
    defholder.setInitParameter("etags", "true");

    String response;

    createFile(file, content);
    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\n\r\n");

    assertResponseContains("200", response);
    assertResponseContains("ETag", response);
    String etag = getHeaderValue("ETag", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-None-Match: "
                + etag
                + "\r\n\r\n");
    assertResponseContains("304", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-None-Match: wibble,"
                + etag
                + ",wobble\r\n\r\n");
    assertResponseContains("304", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-None-Match: wibble\r\n\r\n");
    assertResponseContains("200", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-None-Match: wibble, wobble\r\n\r\n");
    assertResponseContains("200", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-Match: "
                + etag
                + "\r\n\r\n");
    assertResponseContains("200", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-Match: wibble,"
                + etag
                + ",wobble\r\n\r\n");
    assertResponseContains("200", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-Match: wibble\r\n\r\n");
    assertResponseContains("412", response);

    response =
        connector.getResponses(
            "GET /context/file.txt HTTP/1.1\r\nHost:test\r\nConnection:close\r\nIf-Match: wibble, wobble\r\n\r\n");
    assertResponseContains("412", response);
  }