如何从部署的上下文路径中排除路径?

How to exclude a path from the context path of a deployment?

我使用 Jetty 11。我在 /opt/web/mybase/webapps 中有两个上下文文件,一个用于 Certbot (Let's Encrypt),另一个用于根目录下的 Web 应用程序上下文。 The first context file must not redirect from HTTP to HTTPS in order to let Certbot work when the SSL certificate has just been revoked, its context path is /.well-known/acme-challenge. The second context file must redirect from HTTP to HTTPS (by forcing the transport type "confidential" in web.xml), the context path is /, it's similar to this context file. Certbot writes something in /.well-known/acme-challenge and expects to see it at http://example.org/.well-known/acme-challenge.

如何在第二个上下文文件中指示除 /.well-known/acme-challenge 中的内容之外的所有内容都必须由此上下文文件中的 WAR 的 servlet 处理?

您需要信任 servlet 规范请求路径映射规则,事情会变得非常简单。

对于上下文路径,使用最长的匹配。 所以对于上下文 /foo/,以及 /foo/example.txt 的请求,最长的匹配是上下文 /foo

让我们看一下这个例子${jetty.base}

certbot-example/
├── etc/
│   └── keystore.p12
├── start.d/
│   ├── deploy.ini
│   ├── http.ini
│   ├── https.ini
│   ├── server.ini
│   └── ssl.ini
└── webapps/
    ├── ROOT/
    │   ├── index.html
    │   └── WEB-INF/
    │       └── web.xml
    ├── well-known/
    │   └── certbot.txt
    └── well-known.xml

它具有以下配置...

$ java -jar ${JETTY_HOME}/start.jar --list-config
Enabled Modules:
----------------
    0) resources       transitive provider of resources for logging-jetty
    1) logging/slf4j   transitive provider of logging/slf4j for logging-jetty
                       dynamic dependency of logging-jetty
    2) logging-jetty   transitive provider of logging for threadpool
                       transitive provider of logging for bytebufferpool
                       transitive provider of logging for server
    3) bytebufferpool  transitive provider of bytebufferpool for server
                       init template available with --add-module=bytebufferpool
    4) threadpool      transitive provider of threadpool for server
                       init template available with --add-module=threadpool
    5) server          ${jetty.base}/start.d/server.ini
    6) security        transitive provider of security for webapp
    7) servlet         transitive provider of servlet for webapp
    8) webapp          transitive provider of webapp for deploy
                       init template available with --add-module=webapp
    9) deploy          ${jetty.base}/start.d/deploy.ini
   10) http            ${jetty.base}/start.d/http.ini
   11) ssl             ${jetty.base}/start.d/ssl.ini
   12) https           ${jetty.base}/start.d/https.ini

...(snip)... 

Jetty Environment:
-----------------
 jetty.version = 10.0.6
 jetty.tag.version = jetty-10.0.6
 jetty.build = 37e7731b4b142a882d73974ff3bec78d621bd674
 jetty.home = /home/joakim/code/jetty/distros/jetty-home-10.0.6
 jetty.base = /home/joakim/code/jetty/distros/bases/certbot-example

...(snip)... 

Properties:
-----------
  ...(snip)... 
 jetty.httpConfig.securePort = 8443

${jetty.base}/webapps/中包含以下内容...

[certbot-example]$ cat webapps/ROOT/WEB-INF/web.xml 
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1">
  <display-name>Example WebApp</display-name>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>securedapp</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
  </security-constraint>
</web-app>

[certbot-example]$ cat webapps/ROOT/index.html 
<html><body><h2>Hello World!</h2></body></html>

[certbot-example]$ cat webapps/well-known/certbot.txt 
example-cert-bot

[certbot-example]$ cat webapps/well-known.xml 
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Set name="contextPath">/.well-known</Set>
  <Set name="war"><Property name="jetty.webapps" default="." />/well-known</Set>
</Configure>

启动码头后,我们可以看到部署了 2 个 webapps 上下文...

[certbot-example]$ java -jar ../../jetty-home-10.0.6/start.jar
2021-08-06 08:29:27.121:INFO :oejs.Server:main: jetty-10.0.6; built: 2021-06-29T15:28:56.259Z; git: 37e7731b4b142a882d73974ff3bec78d621bd674; jvm 11.0.12+7
2021-08-06 08:29:27.151:INFO :oejdp.ScanningAppProvider:main: Deployment monitor [file:///home/joakim/code/jetty/distros/bases/certbot-example/webapps/]
2021-08-06 08:29:27.227:INFO :oejw.StandardDescriptorProcessor:main: NO JSP Support for /.well-known, did not find org.eclipse.jetty.jsp.JettyJspServlet
2021-08-06 08:29:27.234:INFO :oejss.DefaultSessionIdManager:main: Session workerName=node0
2021-08-06 08:29:27.253:INFO :oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@30bce90b{/.well-known,file:///home/joakim/code/jetty/distros/bases/certbot-example/webapps/well-known/,AVAILABLE}{/home/joakim/code/jetty/distros/bases/certbot-example/webapps/well-known}
2021-08-06 08:29:27.264:INFO :oejw.StandardDescriptorProcessor:main: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
2021-08-06 08:29:27.269:INFO :oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@10cf09e8{Example WebApp,/,file:///home/joakim/code/jetty/distros/bases/certbot-example/webapps/ROOT/,AVAILABLE}{/home/joakim/code/jetty/distros/bases/certbot-example/webapps/ROOT}
2021-08-06 08:29:27.432:INFO :oejus.SslContextFactory:main: x509=X509@57abad67(mykey,h=[localhost],a=[],w=[]) for Server@584f54e6[provider=null,keyStore=file:///home/joakim/code/jetty/distros/bases/certbot-example/etc/keystore.p12,trustStore=null]
2021-08-06 08:29:27.515:INFO :oejs.AbstractConnector:main: Started ServerConnector@1af687fe{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2021-08-06 08:29:27.522:INFO :oejs.AbstractConnector:main: Started ServerConnector@70efb718{SSL, (ssl, http/1.1)}{0.0.0.0:8443}
2021-08-06 08:29:27.534:INFO :oejs.Server:main: Started Server@1e16c0aa{STARTING}[10.0.6,sto=5000] @1071ms

注释的两个条目...

  • 已开始 o.e.j.w.WebAppContext@30bce90b{/.well-known, file:///.../certbot-example/webapps/well-known/, 可用}
  • 已开始 o.e.j.w.WebAppContext@10cf09e8{Web 应用示例,/file:///.../certbot-example/webapps/ROOT/,可用}

这意味着我们定义了 2 个上下文,
一个用于向路径 http://<machine>/.well-known/
提供服务请求 另一个 http://<machine>/

如果我们发出一些请求,您会看到行为...

向上下文发出请求/.well-known(注意 http 和 https 有效)

$ curl -vvv http://localhost:8080/.well-known/certbot.txt
*   Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /.well-known/certbot.txt HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Last-Modified: Fri, 06 Aug 2021 13:11:32 GMT
< Content-Type: text/plain
< Accept-Ranges: bytes
< Content-Length: 17
< Server: Jetty(10.0.6)
< 
example-cert-bot

$ curl -k -vvv https://localhost:8443/.well-known/certbot.txt
*   Trying 127.0.0.1:8443...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
...(snip)...
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET /.well-known/certbot.txt HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/7.68.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Last-Modified: Fri, 06 Aug 2021 13:11:32 GMT
< Content-Type: text/plain
< Accept-Ranges: bytes
< Content-Length: 17
< Server: Jetty(10.0.6)
< 
example-cert-bot

但是,如果我们从上下文中请求某些内容 /,我们只能使用 https。

$ curl -k -L -vvv http://localhost:8080/
*   Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 303 See Other
< Location: https://localhost:8443/
< Content-Length: 0
< Server: Jetty(10.0.6)
< 
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'https://localhost:8443/'
*   Trying 127.0.0.1:8443...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8443 (#1)
* ALPN, offering h2
* ALPN, offering http/1.1
..(snip)...
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET / HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/7.68.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Last-Modified: Fri, 06 Aug 2021 13:08:50 GMT
< Content-Type: text/html
< Accept-Ranges: bytes
< Content-Length: 48
< Server: Jetty(10.0.6)
< 
<html><body><h2>Hello World!</h2></body></html>
* Connection #1 to host localhost left intact