private ServletChain createHandler(
     final DeploymentInfo deploymentInfo,
     final ServletHandler targetServlet,
     final Map<DispatcherType, List<ManagedFilter>> noExtension,
     final String servletPath,
     final boolean defaultServlet) {
   final ServletChain initialHandler;
   if (noExtension.isEmpty()) {
     initialHandler =
         servletChain(
             targetServlet,
             targetServlet.getManagedServlet(),
             servletPath,
             deploymentInfo,
             defaultServlet);
   } else {
     FilterHandler handler =
         new FilterHandler(
             noExtension, deploymentInfo.isAllowNonStandardWrappers(), targetServlet);
     initialHandler =
         servletChain(
             handler,
             targetServlet.getManagedServlet(),
             servletPath,
             deploymentInfo,
             defaultServlet);
   }
   return initialHandler;
 }
  @Test
  public void testReplaceServletHandlerWithServlet() throws Exception {
    ServletContextHandler context = new ServletContextHandler();
    context.addServlet(TestServlet.class, "/test");
    context.setContextPath("/");
    _server.setHandler(context);
    _server.start();

    StringBuffer request = new StringBuffer();
    request.append("GET /test HTTP/1.0\n");
    request.append("Host: localhost\n");
    request.append("\n");

    String response = _connector.getResponses(request.toString());
    assertResponseContains("Test", response);

    context.stop();
    ServletHandler srvHnd = new ServletHandler();
    srvHnd.addServletWithMapping(HelloServlet.class, "/hello");
    context.setServletHandler(srvHnd);
    context.start();

    request = new StringBuffer();
    request.append("GET /hello HTTP/1.0\n");
    request.append("Host: localhost\n");
    request.append("\n");

    response = _connector.getResponses(request.toString());
    assertResponseContains("Hello World", response);
  }
  @Test
  public void testFallThrough() throws Exception {
    HandlerList list = new HandlerList();
    _server.setHandler(list);

    ServletContextHandler root =
        new ServletContextHandler(list, "/", ServletContextHandler.SESSIONS);

    ServletHandler servlet = root.getServletHandler();
    servlet.setEnsureDefaultServlet(false);
    servlet.addServletWithMapping(HelloServlet.class, "/hello/*");

    list.addHandler(
        new AbstractHandler() {
          @Override
          public void handle(
              String target,
              Request baseRequest,
              HttpServletRequest request,
              HttpServletResponse response)
              throws IOException, ServletException {
            response.sendError(404, "Fell Through");
          }
        });

    _server.start();

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

    response = _connector.getResponses("GET /other HTTP/1.0\r\n\r\n");
    Assert.assertThat(response, Matchers.containsString("404 Fell Through"));
  }
    /** @since servlet-api-3.0 */
    @Override
    public FilterRegistration.Dynamic addFilter(String filterName, Filter filter) {
      if (isStarted()) throw new IllegalStateException();

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

      if (!_enabled) throw new UnsupportedOperationException();

      final ServletHandler handler = ServletContextHandler.this.getServletHandler();
      FilterHolder holder = handler.getFilter(filterName);
      if (holder == null) {
        // new filter
        holder = handler.newFilterHolder(Source.JAVAX_API);
        holder.setName(filterName);
        holder.setFilter(filter);
        handler.addFilter(holder);
        return holder.getRegistration();
      }

      if (holder.getClassName() == null && holder.getHeldClass() == null) {
        // preliminary filter registration completion
        holder.setFilter(filter);
        return holder.getRegistration();
      } else return null; // existing filter
    }
    /** @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
    }
  @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);
  }
  /** @param servletHandler The servletHandler to set. */
  public void setServletHandler(ServletHandler servletHandler) {
    if (isStarted()) throw new IllegalStateException("STARTED");

    Handler next = null;
    if (_servletHandler != null) {
      next = _servletHandler.getHandler();
      _servletHandler.setHandler(null);
      replaceHandler(_servletHandler, servletHandler);
    }
    _servletHandler = servletHandler;
    if (next != null && _servletHandler.getHandler() == null) _servletHandler.setHandler(next);
    relinkHandlers();
  }
    @Override
    public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
      if (!_enabled) throw new UnsupportedOperationException();

      HashMap<String, FilterRegistration> registrations = new HashMap<String, FilterRegistration>();
      ServletHandler handler = ServletContextHandler.this.getServletHandler();
      FilterHolder[] holders = handler.getFilters();
      if (holders != null) {
        for (FilterHolder holder : holders)
          registrations.put(holder.getName(), holder.getRegistration());
      }
      return registrations;
    }
Example #9
0
 /* ------------------------------------------------------------ */
 protected void illegalStateIfContextStarted() {
   if (_servletHandler != null) {
     ServletContext context = _servletHandler.getServletContext();
     if ((context instanceof ContextHandler.Context)
         && ((ContextHandler.Context) context).getContextHandler().isStarted())
       throw new IllegalStateException("Started");
   }
 }
  /**
   * Finish constructing handlers and link them together.
   *
   * @see org.eclipse.jetty.server.handler.ContextHandler#startContext()
   */
  @Override
  protected void startContext() throws Exception {
    ServletContainerInitializerCaller sciBean = getBean(ServletContainerInitializerCaller.class);
    if (sciBean != null) sciBean.start();

    if (_servletHandler != null) {
      // Call decorators on all holders, and also on any EventListeners before
      // decorators are called on any other classes (like servlets and filters)
      if (_servletHandler.getListeners() != null) {
        for (ListenerHolder holder : _servletHandler.getListeners()) {
          _objFactory.decorate(holder.getListener());
        }
      }
    }

    super.startContext();

    // OK to Initialize servlet handler now that all relevant object trees have been started
    if (_servletHandler != null) _servletHandler.initialize();
  }
  /**
   * Sets up the handlers in the servlet chain. We setup a chain for every path + extension match
   * possibility. (i.e. if there a m path mappings and n extension mappings we have n*m chains).
   *
   * <p>If a chain consists of only the default servlet then we add it as an async handler, so that
   * resources can be served up directly without using blocking operations.
   *
   * <p>TODO: this logic is a bit convoluted at the moment, we should look at simplifying it
   */
  private ServletPathMatchesData setupServletChains() {
    // create the default servlet
    ServletHandler defaultServlet = null;
    final ManagedServlets servlets = deployment.getServlets();
    final ManagedFilters filters = deployment.getFilters();

    final Map<String, ServletHandler> extensionServlets = new HashMap<>();
    final Map<String, ServletHandler> pathServlets = new HashMap<>();

    final Set<String> pathMatches = new HashSet<>();
    final Set<String> extensionMatches = new HashSet<>();

    DeploymentInfo deploymentInfo = deployment.getDeploymentInfo();

    // loop through all filter mappings, and add them to the set of known paths
    for (FilterMappingInfo mapping : deploymentInfo.getFilterMappings()) {
      if (mapping.getMappingType() == FilterMappingInfo.MappingType.URL) {
        String path = mapping.getMapping();
        if (path.equals("*")) {
          // UNDERTOW-95, support this non-standard filter mapping
          path = "/*";
        }
        if (!path.startsWith("*.")) {
          pathMatches.add(path);
        } else {
          extensionMatches.add(path.substring(2));
        }
      }
    }

    // now loop through all servlets.
    for (Map.Entry<String, ServletHandler> entry : servlets.getServletHandlers().entrySet()) {
      final ServletHandler handler = entry.getValue();
      // add the servlet to the approprite path maps
      for (String path : handler.getManagedServlet().getServletInfo().getMappings()) {
        if (path.equals("/")) {
          // the default servlet
          pathMatches.add("/*");
          if (defaultServlet != null) {
            throw UndertowServletMessages.MESSAGES.twoServletsWithSameMapping(path);
          }
          defaultServlet = handler;
        } else if (!path.startsWith("*.")) {
          // either an exact or a /* based path match
          if (path.isEmpty()) {
            path = "/";
          }
          pathMatches.add(path);
          if (pathServlets.containsKey(path)) {
            throw UndertowServletMessages.MESSAGES.twoServletsWithSameMapping(path);
          }
          pathServlets.put(path, handler);
        } else {
          // an extension match based servlet
          String ext = path.substring(2);
          extensionMatches.add(ext);
          extensionServlets.put(ext, handler);
        }
      }
    }
    ServletHandler managedDefaultServlet = servlets.getServletHandler(DEFAULT_SERVLET_NAME);
    if (managedDefaultServlet == null) {
      // we always create a default servlet, even if it is not going to have any path mappings
      // registered
      managedDefaultServlet =
          servlets.addServlet(new ServletInfo(DEFAULT_SERVLET_NAME, DefaultServlet.class));
    }

    if (defaultServlet == null) {
      // no explicit default servlet was specified, so we register our mapping
      pathMatches.add("/*");
      defaultServlet = managedDefaultServlet;
    }

    final ServletPathMatchesData.Builder builder = ServletPathMatchesData.builder();

    // we now loop over every path in the application, and build up the patches based on this path
    // these paths contain both /* and exact matches.
    for (final String path : pathMatches) {
      // resolve the target servlet, will return null if this is the default servlet
      MatchData targetServletMatch =
          resolveServletForPath(path, pathServlets, extensionServlets, defaultServlet);

      final Map<DispatcherType, List<ManagedFilter>> noExtension =
          new EnumMap<>(DispatcherType.class);
      final Map<String, Map<DispatcherType, List<ManagedFilter>>> extension = new HashMap<>();
      // initalize the extension map. This contains all the filers in the noExtension map, plus
      // any filters that match the extension key
      for (String ext : extensionMatches) {
        extension.put(ext, new EnumMap<DispatcherType, List<ManagedFilter>>(DispatcherType.class));
      }

      // loop over all the filters, and add them to the appropriate map in the correct order
      for (final FilterMappingInfo filterMapping : deploymentInfo.getFilterMappings()) {
        ManagedFilter filter = filters.getManagedFilter(filterMapping.getFilterName());
        if (filterMapping.getMappingType() == FilterMappingInfo.MappingType.SERVLET) {
          if (targetServletMatch.handler != null) {
            if (filterMapping
                .getMapping()
                .equals(
                    targetServletMatch.handler.getManagedServlet().getServletInfo().getName())) {
              addToListMap(noExtension, filterMapping.getDispatcher(), filter);
            }
          }
          for (Map.Entry<String, Map<DispatcherType, List<ManagedFilter>>> entry :
              extension.entrySet()) {
            ServletHandler pathServlet = targetServletMatch.handler;
            boolean defaultServletMatch = targetServletMatch.defaultServlet;
            if (defaultServletMatch && extensionServlets.containsKey(entry.getKey())) {
              pathServlet = extensionServlets.get(entry.getKey());
            }

            if (filterMapping
                .getMapping()
                .equals(pathServlet.getManagedServlet().getServletInfo().getName())) {
              addToListMap(extension.get(entry.getKey()), filterMapping.getDispatcher(), filter);
            }
          }
        } else {
          if (filterMapping.getMapping().isEmpty()
              || !filterMapping.getMapping().startsWith("*.")) {
            if (isFilterApplicable(path, filterMapping.getMapping())) {
              addToListMap(noExtension, filterMapping.getDispatcher(), filter);
              for (Map<DispatcherType, List<ManagedFilter>> l : extension.values()) {
                addToListMap(l, filterMapping.getDispatcher(), filter);
              }
            }
          } else {
            addToListMap(
                extension.get(filterMapping.getMapping().substring(2)),
                filterMapping.getDispatcher(),
                filter);
          }
        }
      }
      // resolve any matches and add them to the builder
      if (path.endsWith("/*")) {
        String prefix = path.substring(0, path.length() - 2);
        // add the default non-extension match
        builder.addPrefixMatch(
            prefix,
            createHandler(
                deploymentInfo,
                targetServletMatch.handler,
                noExtension,
                targetServletMatch.matchedPath,
                targetServletMatch.defaultServlet),
            targetServletMatch.defaultServlet
                || targetServletMatch
                    .handler
                    .getManagedServlet()
                    .getServletInfo()
                    .isRequireWelcomeFileMapping());

        // build up the chain for each non-extension match
        for (Map.Entry<String, Map<DispatcherType, List<ManagedFilter>>> entry :
            extension.entrySet()) {
          ServletHandler pathServlet = targetServletMatch.handler;
          String pathMatch = targetServletMatch.matchedPath;

          boolean defaultServletMatch = targetServletMatch.defaultServlet;
          if (defaultServletMatch && extensionServlets.containsKey(entry.getKey())) {
            defaultServletMatch = false;
            pathServlet = extensionServlets.get(entry.getKey());
          }
          HttpHandler handler = pathServlet;
          if (!entry.getValue().isEmpty()) {
            handler =
                new FilterHandler(
                    entry.getValue(), deploymentInfo.isAllowNonStandardWrappers(), handler);
          }
          builder.addExtensionMatch(
              prefix,
              entry.getKey(),
              servletChain(
                  handler,
                  pathServlet.getManagedServlet(),
                  pathMatch,
                  deploymentInfo,
                  defaultServletMatch));
        }
      } else if (path.isEmpty()) {
        // the context root match
        builder.addExactMatch(
            "/",
            createHandler(
                deploymentInfo,
                targetServletMatch.handler,
                noExtension,
                targetServletMatch.matchedPath,
                targetServletMatch.defaultServlet));
      } else {
        // we need to check for an extension match, so paths like /exact.txt will have the correct
        // filter applied
        String lastSegment = path.substring(path.lastIndexOf('/'));
        if (lastSegment.contains(".")) {
          String ext = lastSegment.substring(lastSegment.lastIndexOf('.') + 1);
          if (extension.containsKey(ext)) {
            Map<DispatcherType, List<ManagedFilter>> extMap = extension.get(ext);
            builder.addExactMatch(
                path,
                createHandler(
                    deploymentInfo,
                    targetServletMatch.handler,
                    extMap,
                    targetServletMatch.matchedPath,
                    targetServletMatch.defaultServlet));
          } else {
            builder.addExactMatch(
                path,
                createHandler(
                    deploymentInfo,
                    targetServletMatch.handler,
                    noExtension,
                    targetServletMatch.matchedPath,
                    targetServletMatch.defaultServlet));
          }
        } else {
          builder.addExactMatch(
              path,
              createHandler(
                  deploymentInfo,
                  targetServletMatch.handler,
                  noExtension,
                  targetServletMatch.matchedPath,
                  targetServletMatch.defaultServlet));
        }
      }
    }

    // now setup name based mappings
    // these are used for name based dispatch
    for (Map.Entry<String, ServletHandler> entry : servlets.getServletHandlers().entrySet()) {
      final Map<DispatcherType, List<ManagedFilter>> filtersByDispatcher =
          new EnumMap<>(DispatcherType.class);
      for (final FilterMappingInfo filterMapping : deploymentInfo.getFilterMappings()) {
        ManagedFilter filter = filters.getManagedFilter(filterMapping.getFilterName());
        if (filterMapping.getMappingType() == FilterMappingInfo.MappingType.SERVLET) {
          if (filterMapping.getMapping().equals(entry.getKey())) {
            addToListMap(filtersByDispatcher, filterMapping.getDispatcher(), filter);
          }
        }
      }
      if (filtersByDispatcher.isEmpty()) {
        builder.addNameMatch(
            entry.getKey(),
            servletChain(
                entry.getValue(),
                entry.getValue().getManagedServlet(),
                null,
                deploymentInfo,
                false));
      } else {
        builder.addNameMatch(
            entry.getKey(),
            servletChain(
                new FilterHandler(
                    filtersByDispatcher,
                    deploymentInfo.isAllowNonStandardWrappers(),
                    entry.getValue()),
                entry.getValue().getManagedServlet(),
                null,
                deploymentInfo,
                false));
      }
    }

    return builder.build();
  }
Example #12
0
  protected void configureHttpServer(HttpServer server) {

    // Favicon hack

    HttpContext faviconContext = new HttpContext();
    faviconContext.setContextPath("/favicon.ico");
    server.addContext(faviconContext);

    ResourceHandler faviconHandler = new ResourceHandler();
    faviconContext.setResourceBase(SysConfig.getStaticDir().getRootPath());
    faviconContext.addHandler(faviconHandler);

    faviconContext.addHandler(new NotFoundHandler());

    // robots.txt hack

    HttpContext robotsContext = new HttpContext();
    robotsContext.setContextPath("/robots.txt");
    server.addContext(robotsContext);

    ResourceHandler robotsHandler = new ResourceHandler();
    robotsContext.setResourceBase(SysConfig.getStaticDir().getRootPath());
    robotsContext.addHandler(robotsHandler);

    robotsContext.addHandler(new NotFoundHandler());

    // Dynamic content

    HttpContext servletContext = new HttpContext();
    servletContext.setContextPath("/");
    server.addContext(servletContext);

    ServletHandler servlets = new ServletHandler();
    servletContext.addHandler(servlets);
    servlets.addServlet("/*", "org.wahlzeit.main.MainServlet");

    servletContext.addHandler(new NotFoundHandler());

    // Photos content

    HttpContext photosContext = new HttpContext();
    photosContext.setContextPath(SysConfig.getPhotosDirAsString());
    server.addContext(photosContext);

    ResourceHandler photosHandler = new ResourceHandler();
    photosContext.setResourceBase(SysConfig.getPhotosDirAsString());
    photosContext.addHandler(photosHandler);

    photosContext.addHandler(new NotFoundHandler());

    // Static content

    HttpContext staticContext = new HttpContext();
    staticContext.setContextPath(SysConfig.getStaticDir().getRootPath());
    server.addContext(staticContext);

    ResourceHandler staticHandler = new ResourceHandler();
    staticContext.setResourceBase(SysConfig.getStaticDir().getRootPath());
    staticContext.addHandler(staticHandler);

    staticContext.addHandler(new NotFoundHandler());
  }