Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.0.x-coreMultiPart

This commit is contained in:
Lachlan Roberts 2024-06-24 12:44:22 +10:00
commit c7249c7156
368 changed files with 6852 additions and 1554 deletions

View File

@ -8,7 +8,7 @@ labels: Enhancement
---
**Jetty version(s)**
_[Jetty 9.x is now at End of Community Support](https://github.com/eclipse/jetty.project/issues/7958)_
_[Jetty 9.x is now at End of Community Support](https://github.com/jetty/jetty.project/issues/7958)_
**Enhancement Description**

View File

@ -8,7 +8,7 @@ labels: Bug
---
**Jetty version(s)**
<!--[Jetty 9.x is now at End of Community Support](https://github.com/eclipse/jetty.project/issues/7958) -->
<!--[Jetty 9.x is now at End of Community Support](https://github.com/jetty/jetty.project/issues/7958) -->
**Jetty Environment**
<!-- Applicable for jetty-12 only, choose: core, ee8, ee9, ee10 -->

View File

@ -1,7 +1,7 @@
# Contributing to Jetty
Contributions are always welcome!
Please see our [Contribution Guide](https://eclipse.dev/jetty/documentation/contribution-guide/index.html) for instructions on how to set up your development environment, as well as information on our processes and coding standards.
Please see our [Contribution Guide](https://jetty.org/docs/contribution-guide/index.html) for instructions on how to set up your development environment, as well as information on our processes and coding standards.
Here are some quick links to other useful resources:
@ -9,7 +9,7 @@ Here are some quick links to other useful resources:
* [**Mailing list.**](https://accounts.eclipse.org/mailing-list/jetty-users) The [`jetty-users@eclipse.org`](mailto:jetty-users@eclipse.org) mailing list is a forum for technical discussion.
* [**Issue tracking.**](https://github.com/jetty/jetty.project/issues) We use [GitHub Issues](https://github.com/eclipse/jetty.project/issues) to track ongoing development and issues.
* [**Issue tracking.**](https://github.com/jetty/jetty.project/issues) We use [GitHub Issues](https://github.com/jetty/jetty.project/issues) to track ongoing development and issues.
## Eclipse Contributor Agreement

2
Jenkinsfile vendored
View File

@ -127,7 +127,7 @@ def mavenBuild(jdk, cmdline, mvnName) {
}
finally
{
junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml', allowEmptyResults: true
junit testResults: '**/target/surefire-reports/**/*.xml,**/target/invoker-reports/TEST*.xml', allowEmptyResults: true
}
}
}

View File

@ -2,7 +2,7 @@ Notices for Eclipse Jetty
=========================
This content is produced and maintained by the Eclipse Jetty project.
Project home: https://eclipse.dev/jetty/
Project home: https://jetty.org/
Trademarks
----------

View File

@ -4,7 +4,7 @@ Eclipse Jetty is a lightweight, highly scalable, Java-based web server and Servl
Jetty's goal is to support web protocols (HTTP/1, HTTP/2, HTTP/3, WebSocket, etc.) in a high volume low latency way that provides maximum performance while retaining the ease of use and compatibility with years of Servlet development.
Jetty is a modern fully asynchronous web server that has a long history as a component oriented technology, and can be easily embedded into applications while still offering a solid traditional distribution for webapp deployment.
- https://eclipse.dev/jetty/
- https://jetty.org
- https://projects.eclipse.org/projects/rt.jetty
## Webapp Example
@ -48,24 +48,24 @@ server.start();
## Building Jetty from Source
```shell
$ git clone https://github.com/eclipse/jetty.project.git
$ git clone https://github.com/jetty/jetty.project.git
$ cd jetty.project
$ mvn -Pfast clean install # fast build bypasses tests and other checks
```
For more detailed information on building and contributing to the Jetty project, please see the [Contribution Guide](https://eclipse.dev/jetty/documentation/contribution-guide/index.html).
For more detailed information on building and contributing to the Jetty project, please see the [Contribution Guide](https://jetty.org/docs/contribution-guide/index.html).
# Documentation
[Jetty's documentation](https://eclipse.dev/jetty/documentation) is available on the Eclipse Jetty website.
[Jetty's documentation](https://jetty.org/docs) is available on the Eclipse Jetty website.
The documentation is divided into three guides, based on use case:
* The [Operations Guide](https://eclipse.dev/jetty/documentation/jetty-12/operations-guide/index.html) targets sysops, devops, and developers who want to install Eclipse Jetty as a standalone server to deploy web applications.
* The [Operations Guide](https://jetty.org/docs/jetty/12/operations-guide/index.html) targets sysops, devops, and developers who want to install Eclipse Jetty as a standalone server to deploy web applications.
* The [Programming Guide](https://eclipse.dev/jetty/documentation/jetty-12/programming-guide/index.html) targets developers who want to use the Eclipse Jetty libraries in their applications, and advanced sysops/devops that want to customize the deployment of web applications.
* The [Programming Guide](https://jetty.org/docs/jetty/12/programming-guide/index.html) targets developers who want to use the Eclipse Jetty libraries in their applications, and advanced sysops/devops that want to customize the deployment of web applications.
* The [Contribution Guide](https://eclipse.dev/jetty/documentation/contribution-guide/index.html) targets developers that wish to contribute to the Jetty Project with code patches or documentation improvements.
* The [Contribution Guide](https://jetty.org/docs/contribution-guide/index.html) targets developers that wish to contribute to the Jetty Project with code patches or documentation improvements.
# Commercial Support

View File

@ -2,7 +2,7 @@
## Supported Versions
All [stable versions](https://eclipse.dev/jetty/download.php) of jetty are actively supported for security issues. [Deprecated versions](https://eclipse.dev/jetty/download.php) may be supported for serious security issues or on a commercial support basis.
All [stable versions](https://jetty.org/download.html) of jetty are actively supported for security issues. [Deprecated versions](https://jetty.org/download.html) may be supported for serious security issues or on a commercial support basis.
## Reporting a Vulnerability
@ -10,7 +10,7 @@ Do not open a public issue to report a security vulnerability. Please send a me
## Handling a Vulnerability
The [following checklist](https://eclipse.dev/jetty/security_processes.php) is used to handle security issues:
The following checklist is used to handle security issues:
- [ ] On receipt of a security report via security@webtide.com or other channels, if it cannot be trivially dismissed (already fixed, known not a problem, etc.), then a Github security advisory is created by project leadership.
- [ ] Copy this list as a markdown in the security advisory for tracking the completion of various tasks.

View File

@ -414,6 +414,8 @@ jetty-10.0.18 - 26 October 2023
+ 10537 HTTP/3: Incomplete Data Transfer When Used with Spring Boot WebFlux
+ 10696 jetty.sh doesn't work with JETTY_USER in Jetty 10.0.17 thru Jetty
12.0.2
+ 10669 Provide ability to defer initial deployment of webapps until after
Server has started
+ 10705 Creating a `HTTP3ServerConnector` with a `SslContextFactory` that has
a non-null `SSLContext` makes the server fail to start with an unclear error
message

View File

@ -36,15 +36,15 @@ In particular, the https://stackoverflow.com/questions/tagged/jetty[`jetty`] and
[[cg-intro-filing-issues]]
=== Filing Issues
You can flag potential bugs or suggest new Jetty features on our https://github.com/eclipse/jetty.project/issues[issue tracker].
You can flag potential bugs or suggest new Jetty features on our https://github.com/jetty/jetty.project/issues[issue tracker].
Before filing a new issue, https://github.com/eclipse/jetty.project/issues[check the tracker] to see if it's already been filed by someone else.
Before filing a new issue, https://github.com/jetty/jetty.project/issues[check the tracker] to see if it's already been filed by someone else.
If you do file an issue, make sure to label it appropriately, as this will help the development team (and other users) find it more easily.
[[cg-intro-help-wanted]]
=== Help Wanted
If you want to contribute to Jetty but don't have a specific task or goal in mind, consider looking through our https://github.com/eclipse/jetty.project/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22["Help Wanted" issue backlog].
If you want to contribute to Jetty but don't have a specific task or goal in mind, consider looking through our https://github.com/jetty/jetty.project/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22["Help Wanted" issue backlog].
These tasks range from the simple to the complex, but they're all ones we've identified as being particularly well-suited for new contributors to tackle.

View File

@ -14,18 +14,18 @@
[[cg-source]]
== Getting the source code
Jetty's source is maintained on GitHub at https://github.com/eclipse/jetty.project, where it is managed by the http://github.com/eclipse/[Eclipse Foundation].
Jetty's source is maintained on GitHub at https://github.com/jetty/jetty.project, where it is managed by the http://github.com/eclipse/[Eclipse Foundation].
You can clone a copy of the Jetty repo onto your local machine by running:
----
git clone https://github.com/eclipse/jetty.project.git
git clone https://github.com/jetty/jetty.project.git
----
[[cg-source-repositories]]
=== Related repositories
In addition to the https://github.com/eclipse/jetty.project[Jetty code repository], we maintain a number of related repositories:
In addition to the https://github.com/jetty/jetty.project[Jetty code repository], we maintain a number of related repositories:
Non-Eclipse Jetty Repositories:: https://github.com/jetty-project
Build Toolchain:: https://github.com/eclipse/jetty.toolchain
@ -37,10 +37,10 @@ If you plan to work on a specific issue within Jetty, make sure to target the co
.Active Jetty branches
[cols="4"]
|===
| https://github.com/eclipse/jetty.project/tree/jetty-12.0.x[jetty-12.0.x] | Development (default branch) | Servlet 6.0 | Java 17+
| https://github.com/eclipse/jetty.project/tree/jetty-11.0.x[jetty-11.0.x] | Maintenance | Servlet 5.0 | Java 11+
| https://github.com/eclipse/jetty.project/tree/jetty-10.0.x[jetty-10.0.x] | Maintenance | Servlet 4.0 | Java 11+
| https://github.com/eclipse/jetty.project/tree/jetty-9.4.x[jetty-9.4.x] | link:https://github.com/eclipse/jetty.project/issues/7958[End of Community Support] | Servlet 3.1 | Java 8+
| https://github.com/jetty/jetty.project/tree/jetty-12.0.x[jetty-12.0.x] | Development (default branch) | Servlet 6.0 | Java 17+
| https://github.com/jetty/jetty.project/tree/jetty-11.0.x[jetty-11.0.x] | Maintenance | Servlet 5.0 | Java 11+
| https://github.com/jetty/jetty.project/tree/jetty-10.0.x[jetty-10.0.x] | Maintenance | Servlet 4.0 | Java 11+
| https://github.com/jetty/jetty.project/tree/jetty-9.4.x[jetty-9.4.x] | link:https://github.com/jetty/jetty.project/issues/7958[End of Community Support] | Servlet 3.1 | Java 8+
|===
Maintenance branches are periodically merged into active development branches.

View File

@ -69,7 +69,7 @@ $ ulimit -n [new_value]
.Flagging flaky tests
====
Not all test cases are as timing independent as they should be, which can result in intermittent test failures.
You can help us track these flaky tests by opening an https://github.com/eclipse/jetty.project/issues[issue] when you come across one.
You can help us track these flaky tests by opening an https://github.com/jetty/jetty.project/issues[issue] when you come across one.
====
[[cg-build-cache]]

View File

@ -20,13 +20,13 @@ This section outlines the various coding conventions and standards we use throug
IntelliJ IDE::
An IntelliJ code style XML file is available in the source repo at
https://github.com/eclipse/jetty.project/blob/jetty-10.0.x/build-resources/jetty-codestyle-intellij.xml[`/build-resources/jetty-codestyle-intellij.xml`]
https://github.com/jetty/jetty.project/blob/jetty-10.0.x/build-resources/jetty-codestyle-intellij.xml[`/build-resources/jetty-codestyle-intellij.xml`]
// TODO: The above link points to the jetty-10.0.x branch, but it doesn't look like there's a `build-resources` directory for jetty-12.0.x.
Follow https://www.jetbrains.com/help/idea/configuring-code-style.html#import-export-schemes[IntelliJ's documentation] to import these settings into your IDE.
Eclipse IDE::
An Eclipse code style XML file is available in the source repo at
https://github.com/eclipse/jetty.project/blob/jetty-10.0.x/build-resources/jetty-codestyle-eclipse-ide.xml[`/build-resources/jetty-codestyle-eclipse-ide.xml`].
https://github.com/jetty/jetty.project/blob/jetty-10.0.x/build-resources/jetty-codestyle-eclipse-ide.xml[`/build-resources/jetty-codestyle-eclipse-ide.xml`].
[[cg-code-standards-java]]
=== Java conventions

View File

@ -32,7 +32,7 @@ Targets developers and writers who want to make contributions to the Jetty proje
[[cg-documentation-toolchain]]
=== The documentation toolchain
Jetty follows a https://www.writethedocs.org/guide/docs-as-code/["docs as code"] philosophy, meaning *we use the same tools to write and build our code and docs*.
As such, the docs are maintained directly within the Jetty codebase at https://github.com/eclipse/jetty.project/tree/jetty-12.0.x/documentation/jetty-documentation/src/main/asciidoc[`documentation/jetty-documentation/src/main/asciidoc/`].
As such, the docs are maintained directly within the Jetty codebase at https://github.com/jetty/jetty.project/tree/jetty-12.0.x/documentation/jetty-documentation/src/main/asciidoc[`documentation/jetty-documentation/src/main/asciidoc/`].
[[cg-documentation-asciidoc]]
==== AsciiDoc
@ -83,13 +83,13 @@ When the build completes, you can view the generated docs in your preferred web
[[cg-documentation-build-structure]]
==== Documentation project structure
The documentation root is https://github.com/eclipse/jetty.project/tree/jetty-10.0.x/documentation/jetty-documentation[`documentation/jetty-documentation/`].
The documentation root is https://github.com/jetty/jetty.project/tree/jetty-10.0.x/documentation/jetty-documentation[`documentation/jetty-documentation/`].
Within this root directory are some files and subdirectories of note:
https://github.com/eclipse/jetty.project/tree/jetty-10.0.x/documentation/jetty-documentation/src/main/asciidoc[`src/main/asciidoc`]::
https://github.com/jetty/jetty.project/tree/jetty-10.0.x/documentation/jetty-documentation/src/main/asciidoc[`src/main/asciidoc`]::
The primary root for all documentation content.
https://github.com/eclipse/jetty.project/tree/jetty-10.0.x/documentation/jetty-documentation/src/main/asciidoc/config.adoc[`src/main/asciidoc/config.adoc`]::
https://github.com/jetty/jetty.project/tree/jetty-10.0.x/documentation/jetty-documentation/src/main/asciidoc/config.adoc[`src/main/asciidoc/config.adoc`]::
This file contains metadata and global variables shared across all the xref:cg-documentation-guides[documentation guides].
This configuration is used by Asciidoctor to correctly render the final docs.

View File

@ -23,7 +23,7 @@ The Eclipse Jetty Operations Guide targets sysops, devops, and developers who wa
The Eclipse Jetty Programming Guide targets developers who want to use the Eclipse Jetty libraries in their applications, and advanced sysops/devops that want to customize the deployment of web applications.
== https://eclipse.dev/jetty/documentation/contribution-guide/index.html[Jetty Contribution Guide]
== https://jetty.org/docs/contribution-guide/index.html[Jetty Contribution Guide]
The Eclipse Jetty Programming Guide targets developers that wish to contribute to the Jetty Project with code patches or documentation improvements.

View File

@ -17,7 +17,7 @@
==== Setting up the Classpath
You will need to place the following Jetty jar files onto the classpath of your application.
You can obtain them from the https://eclipse.dev/jetty/download.html[Jetty distribution], or the https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-annotations[Maven repository]:
You can obtain them from the https://jetty.org/download.html[Jetty distribution], or the https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-annotations[Maven repository]:
....
jetty-plus.jar

View File

@ -72,7 +72,7 @@ Context files are normally located in `${jetty.base}/webapps/` (see `DeployerMan
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="contextPath">/test</Set>

View File

@ -17,5 +17,5 @@
As with any constantly evolving software project, there will be issues, features, and bugs.
We want to know whats bugging you!
File bugs as Issues in our Github repository http://github.com/eclipse/jetty.project[Issues at Github]
File bugs as Issues in our Github repository http://github.com/jetty/jetty.project[Issues at Github]

View File

@ -49,7 +49,7 @@ Clone the repository:
[source, screen, subs="{sub-order}"]
....
$ git clone https://github.com/eclipse/jetty.project.git
$ git clone https://github.com/jetty/jetty.project.git
....
You will now have a local directory with all of jetty, including the jetty-documentation.
@ -109,7 +109,7 @@ Obviously we can not allow anyone immediate access to this repository so you mus
In English that means that you would go to the url of the documentation in github:
....
https://github.com/eclipse/jetty.project
https://github.com/jetty/jetty.project
....
When you are on this page you will see a little button called 'Fork' which you can click and you will be taken back to your main page on github where you have a new repository.

View File

@ -230,7 +230,7 @@ There are two git repositories you need to be aware of for releasing jetty-docum
jetty-documentation::
https://github.com/jetty-project/jetty-documentation
jetty-website::
http://git.eclipse.org/c/www.eclipse.org/jetty.git
http://github.com/jetty/jetty.website
Do the following steps to publish documentation for the release:
@ -246,7 +246,7 @@ Make sure you follow the other examples and include the `rel="nofollow"` attribu
____
[NOTE]
There is a separate Jenkins build job that publishes documentation to https://eclipse.dev/jetty/documentation/ triggered by a push of changed files to the jetty-documentation project.
There is a separate Jenkins build job that publishes documentation to https://jetty.org/docs/ triggered by a push of changed files to the jetty-documentation project.
If you commit your change to the <version> number from step 2, then these builds will use the same release version number.
It is preferable if you _don't_ commit that version number change, or better yet, ensure that it is set to the next -SNAPSHOT version number for your jetty major release number.
____

View File

@ -28,7 +28,7 @@ These are the URLs to the GIT repositories for the Jetty code.
They are for people who are working on the Jetty project, as well as for people who are interested in examining or modifying the Jetty code for their own projects.
Jetty Project Repository::
https://github.com/eclipse/jetty.project
https://github.com/jetty/jetty.project
===== Build and Project Infrastructure SCM URLs
@ -53,7 +53,7 @@ Building Jetty should simply be a matter of changing into the relevant directory
[source, screen, subs="{sub-order}"]
....
$ git clone https://github.com/eclipse/jetty.project.git
$ git clone https://github.com/jetty/jetty.project.git
$ cd jetty.project
$ mvn install

View File

@ -41,7 +41,7 @@ For example, here is a descriptor file that deploys the file `/opt/myapp/myapp.w
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="contextPath">/wiki</Set>
@ -55,7 +55,7 @@ For example, if the system property is set to `myapp.home=/opt/myapp`, the previ
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="contextPath">/wiki</Set>
@ -83,7 +83,7 @@ This can help make it clear that users should not make changes to the temporary
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="contextPath">/wiki</Set>
@ -99,7 +99,7 @@ However, since the `web.xml` for the web application is processed after the depl
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="contextPath">/wiki</Set>
@ -120,7 +120,7 @@ This feature is useful when adding parameters or additional Servlet mappings wit
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="contextPath">/wiki</Set>
@ -135,7 +135,7 @@ If the `web.xml` does not include a reference to this data source, an override d
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="contextPath">/wiki</Set>

View File

@ -99,7 +99,7 @@ In the standard Jetty Distribution, this is configured in the `${jetty.home}/etc
[source,xml,subs="{sub-order}"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addBean">

View File

@ -130,7 +130,7 @@ Let's see an example of how we would add in the Configurations for both JNDI _an
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
@ -162,7 +162,7 @@ They will then be applied to each `WebAppContext` deployed by the deployer:
[source,xml,subs="{sub-order}"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
@ -206,7 +206,7 @@ This example uses an xml file, in fact it is the `$JETTY_HOME/etc/jetty-plus.xml
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
@ -256,7 +256,7 @@ Here's an example from a context xml file (although as always, you could have ac
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
@ -282,7 +282,7 @@ Here's an example in a xml file of a pattern that matches any jar that starts wi
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">

View File

@ -100,7 +100,7 @@ Otherwise, create a context xml file with the following information (in addition
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.quickstart.QuickStartWebApp">
<Set name="autoPreconfigure">true</Set>
</Configure>

View File

@ -20,7 +20,7 @@ Create a file called `scratch.xml` in the `${jetty.base}/webapps` directory and
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="contextPath">/scratch</Set>
<Set name="handler">

View File

@ -43,7 +43,7 @@ This is a permanent redirection, which also preserves `pathinfo` and query strin
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.server.handler.MovedContextHandler">
<Set name="contextPath">/foo</Set>

View File

@ -73,7 +73,7 @@ This module is equivalent to directly modifying the class path configuration wit
[source.XML, xml]
-------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://eclipse.dev/jetty/configure.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Call name="prependServerClass">
<Arg>-org.eclipse.jetty.util.Decorator</Arg>

View File

@ -24,7 +24,7 @@ In addition, the infrastructure also supports the OSGi `HttpService` interface.
All of the Jetty jars contain manifest entries appropriate to ensure that they can be deployed into an OSGi container as bundles.
You will need to install some jetty jars into your OSGi container.
You can always find the Jetty jars either in the Maven Central repository, or you can link:https://eclipse.dev/jetty/download.php[download] a distribution of Jetty.
You can always find the Jetty jars either in the Maven Central repository, or you can link:https://jetty.org/download.html[download] a distribution of Jetty.
Here's the absolute minimal set of Jetty jars:
.Minimal Bundles
@ -355,7 +355,7 @@ Here's an example of the contents of a `META-INF/jetty-webapp-context.xml` file:
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="defaultsDescriptor"><Property name="bundle.root"/>META-INF/webdefault.xml</Set>
@ -773,7 +773,7 @@ To set the pattern, you will need to provide your own etc files - see the sectio
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addBean">
<Arg>

View File

@ -140,7 +140,7 @@ The deployer discovers and hot deploys context IoC descriptors like the followin
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<!--
Configure a custom context for serving javadoc as static resources
@ -199,7 +199,7 @@ To set the contextPath from within the WAR file, you can include a `WEB-INF/jett
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="contextPath">/contextpath</Set>
@ -212,7 +212,7 @@ Instead of allowing the WAR file to be discovered by the deployer, an IoC XML fi
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test.war</Set>

View File

@ -19,7 +19,7 @@
The standalone Jetty distribution is available for download from the Eclipse Foundation:
____
*Jetty*
https://eclipse.dev/jetty/download.php
https://jetty.org/download.html
____
It is available in both zip and gzip formats; download the one most appropriate for your system.

View File

@ -24,7 +24,7 @@ To start Jetty on the default port of 8080, run the following command:
----
$ java -jar start.jar
2017-09-20 15:45:11.986:INFO::main: Logging initialized @683ms to org.eclipse.jetty.util.log.StdErrLog
2017-09-20 15:45:12.197:WARN:oejs.HomeBaseWarning:main: This instance of Jetty is not running from a separate {jetty.base} directory, this is not recommended. See documentation at https://eclipse.dev/jetty/documentation/
2017-09-20 15:45:12.197:WARN:oejs.HomeBaseWarning:main: This instance of Jetty is not running from a separate {jetty.base} directory, this is not recommended. See documentation at https://jetty.org/docs/
2017-09-20 15:45:12.243:INFO:oejs.Server:main: {VERSION}
2017-09-20 15:45:12.266:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///installs/repository/jetty/webapps/] at interval 1
2017-09-20 15:45:12.298:INFO:oejs.AbstractConnector:main: Started ServerConnector@39c0f4a{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}

View File

@ -1,7 +1,7 @@
/*
* GraphViz Graph of Jetty Modules
*
* Jetty: https://eclipse.dev/jetty/
* Jetty: https://jetty.org/
* GraphViz: http://graphviz.org/
*
* To Generate Graph image using graphviz:

View File

@ -29,7 +29,7 @@ Jetty applies `jetty-env.xml` on a per-webapp basis, and configures an instance
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
..
@ -52,7 +52,7 @@ Place the `jetty-env.xml` file in your web application's WEB-INF folder.
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">

View File

@ -28,7 +28,7 @@ For a more in-depth look at the syntax, see xref:jetty-xml-syntax[].
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
..

View File

@ -26,7 +26,7 @@
Not all Jetty features are configured in `jetty.xml`.
There are several optional configuration files that share the same format as `jetty.xml` and, if specified, concatenate to it.
These configuration files are also stored in `$JETTY_HOME/etc/`, and examples of them are in http://github.com/eclipse/jetty.project/jetty-server/src/main/config/etc/[Github Repository].
These configuration files are also stored in `$JETTY_HOME/etc/`, and examples of them are in http://github.com/jetty/jetty.project/jetty-server/src/main/config/etc/[Github Repository].
The selection of which configuration files to use is controlled by `start.jar` and the process of merging configuration is described in xref:jetty-xml-usage[].
[[root-element-jetty-xml]]
@ -38,7 +38,7 @@ The selection of which configuration files to use is controlled by `start.jar` a
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
...

View File

@ -20,7 +20,7 @@ In addition to using Jetty in its distribution form and its multiple embedded fo
Many products and open source projects out there distribute Jetty themselves, in both distribution and embedded forms, not to mention different operating systems bundling Jetty in other installable forms.
If your platform supports Jetty from a distribution or deployment perspective and want to be included on this list just fork the documentation and submit a pull request, or contact us.
Check out our list of https://eclipse.dev/jetty/powered[Powered By] page for software that makes use of Jetty, often in novel and exciting ways.
Check out our list of https://jetty.org/powered[Powered By] page for software that makes use of Jetty, often in novel and exciting ways.
include::jelastic.adoc[]
include::cloudfoundry.adoc[]

View File

@ -69,7 +69,7 @@ The default Configuration Classes are:
`org.eclipse.jetty.plus.webapp.PlusConfiguration`
`org.eclipse.jetty.annotations.AnnotationConfiguration`
You can learn more about implementing specific Configuration Classes link:https://eclipse.dev/jetty/documentation/[in the Jetty documentation.]
You can learn more about implementing specific Configuration Classes link:https://jetty.org/docs/[in the Jetty documentation.]
==== Deploying Multiple Contexts

View File

@ -406,4 +406,4 @@ public class FooLoginModule extends AbstractLoginModule
An example webapp using JAAS can be found in the Jetty GitHub repository:
* link:{GITBROWSEURL}/tests/test-webapps/test-jaas-webapp[https://github.com/eclipse/jetty.project/tree/jetty-12.0.x/tests/test-webapps/test-jaas-webapp]
* link:{GITBROWSEURL}/tests/test-webapps/test-jaas-webapp[https://github.com/jetty/jetty.project/tree/jetty-12.0.x/tests/test-webapps/test-jaas-webapp]

View File

@ -16,7 +16,7 @@
==== List of Security Reports
A current list of Jetty security reports can be viewed on the link:https://eclipse.dev/jetty/security-reports.php[Project Home Page.]
A current list of Jetty security reports can be viewed on the link:https://jetty.org/security-reports.php[Project Home Page.]
==== Reporting Security Issues

View File

@ -48,7 +48,7 @@ Here's an example context XML file that calls this method:
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Set name="configurationDiscovered">false</Set> <!--2-->
@ -77,7 +77,7 @@ Here's an example from a context XML file that includes any jar whose name start
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->
@ -108,7 +108,7 @@ Here's an example of a context XML file that sets a pattern that matches any jar
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->
@ -174,7 +174,7 @@ Here's an example of setting the context attribute in a context XML file:
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->
@ -205,7 +205,7 @@ Here is an example context XML file that ensures the `com.example.PrioritySCI` w
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->

View File

@ -14,6 +14,6 @@
[[og-begin-download]]
==== Downloading Jetty
The Jetty distribution is a file of the form `jetty-home-<version>.<ext>`, available for download from link:https://eclipse.dev/jetty/download.php[]
The Jetty distribution is a file of the form `jetty-home-<version>.<ext>`, available for download from link:https://jetty.org/download.html[]
The Jetty distribution is available in both `zip` and `gzip` formats; download the one most appropriate for your system, typically `zip` for Windows and `gzip` for other operating systems.

View File

@ -24,7 +24,7 @@ If you do not want Jetty to extract the `+*.war+` files, you can disable this fe
[source,xml,subs="verbatim,attributes,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/mywebapp</Set>

View File

@ -26,7 +26,7 @@ A simple Jetty context XML file, for example named `wiki.xml` is the following:
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Set name="contextPath">/wiki</Set> <!--2-->
@ -71,7 +71,7 @@ You can use the features of xref:og-xml[Jetty XML files] to avoid to hard-code f
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/wiki</Set>

View File

@ -21,7 +21,7 @@ The JNDI entry must be _defined_ in a xref:og-jndi-xml[Jetty XML file], for exam
[source,xml,subs="verbatim,attributes,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="wac" class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/mywebapp</Set>

View File

@ -22,7 +22,7 @@ This allows you to add host specific configuration or server specific configurat
[source,xml,subs="verbatim,attributes,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/mywebapp</Set>

View File

@ -56,7 +56,7 @@ If you have a web application `mywebapp.war` you can configure its virtual hosts
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/mywebapp</Set>
@ -101,7 +101,7 @@ To achieve this, you simply use the same context path of `/` for each of your we
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/</Set>
@ -118,7 +118,7 @@ To achieve this, you simply use the same context path of `/` for each of your we
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/</Set>
@ -146,7 +146,7 @@ In this case, you want to xref:og-protocols[configure multiple connectors], each
[source,xml,subs="verbatim,attributes,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/</Set>
@ -163,7 +163,7 @@ In this case, you want to xref:og-protocols[configure multiple connectors], each
[source,xml,subs="verbatim,attributes,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/</Set>

View File

@ -97,7 +97,7 @@ Here's an example of this type of XML file:
[source,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addBean">
<Arg>
@ -115,7 +115,7 @@ Here's an example of this type of XML file:
[source,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="securityHandler">
<New class="org.eclipse.jetty.security.ConstraintSecurityHandler">

View File

@ -197,7 +197,7 @@ Here's an example of using a context xml file to add in a pattern to match files
[source,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->

View File

@ -38,7 +38,7 @@ An example of `jetty-rewrite-rules.xml` is the following:
.jetty-rewrite-rules.xml
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
<Call name="addRule">
<!-- Redirect with a 301 from /old/* to /new/* -->
@ -60,7 +60,7 @@ In the example below, the rule will only be evaluated if the virtual host matche
.jetty-rewrite-rules.xml
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
<Call name="addRule">
<Arg>

View File

@ -43,7 +43,7 @@ Start with the custom Jetty XML file, `$JETTY_BASE/etc/custom-ssl.xml`:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Ref refid="sslContextFactory"> <!--1-->
<Set name="CipherComparator"> <!--2-->
@ -159,7 +159,7 @@ Next, let's write the Jetty XML file that wires the auditing component to the `S
[source,xml,options=nowrap]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Ref refid="Server"> <!--1-->
<Call name="insertHandler"> <!--2-->

View File

@ -85,7 +85,7 @@ For example, a Jetty XML file that allocates Jetty's `QueuedThreadPool` could be
.jetty-threadpool.xml
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<New id="threadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="maxThreads" type="int">
@ -235,7 +235,7 @@ The `custom-server.xml` file is the following:
[source,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Server" class="com.acme.server.CustomJettyServer">
</Configure>
----

View File

@ -79,7 +79,7 @@ Use the following file as example, copy it as `$JETTY_BASE/webapps/wordpress.xml
[source,xml,options=nowrap]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
<New id="root" class="java.lang.String">

View File

@ -59,7 +59,7 @@ You want to create the `$JETTY_BASE/etc/tls-config.xml` with the following templ
[source,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Ref refid="sslContextFactory">
@ -85,7 +85,7 @@ To explicitly add the exclusion of TLSv1.0 and TLSv1.1 (that are also vulnerable
[source,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Ref refid="sslContextFactory">
@ -110,7 +110,7 @@ You can precisely set the list of excluded ciphers, completely overriding Jetty'
[source,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Ref refid="sslContextFactory">

View File

@ -126,7 +126,7 @@ There are no configuration properties associated with this module.
From Jetty-9.4.13 onwards, we have changed the format of the serialized session when using a remote cache (ie using hotrod).
Prior to release 9.4.13 we used the default Infinispan serialization, however this was not able to store sufficient information to allow Jetty to properly deserialize session attributes in all circumstances.
See issue link:https://github.com/eclipse/jetty.project/issues/2919[] for more background.
See issue link:https://github.com/jetty/jetty.project/issues/2919[] for more background.
We have provided a conversion program which will convert any sessions stored in Infinispan to the new format.

View File

@ -21,7 +21,7 @@ The Jetty XML elements define attributes such as `id`, `name`, `class`, etc. tha
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Get id="stderr" class="java.lang.System" name="err">
@ -33,7 +33,7 @@ The Jetty XML elements define attributes such as `id`, `name`, `class`, etc. tha
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Get>
@ -60,7 +60,7 @@ The following Jetty XML creates an empty `String` and assigns it the id `mystrin
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="mystring" class="java.lang.String" />
----
@ -88,7 +88,7 @@ The following example creates a minimal Jetty `Server`:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.server.Server">
<Arg type="int">8080</Arg>
@ -102,7 +102,7 @@ Arguments may also have a `name` attribute, which is matched with the correspond
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.server.Server">
<Arg name="port" type="int">8080</Arg>
@ -122,7 +122,7 @@ The following example creates an `ArrayList`:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<New id="mylist" class="java.util.ArrayList">
@ -149,7 +149,7 @@ Within element `<Call>` the return value, if the return type is not `void`, is i
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<New class="java.util.ArrayList">
@ -173,7 +173,7 @@ It is possible to call `static` methods by specifying the `class` attribute:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Call id="myhost" name="getByName" class="java.net.InetAddress">
@ -196,7 +196,7 @@ For example:
[source,xml,subs="verbatim,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Call class="java.util.concurrent.Executors" name="newSingleThreadScheduledExecutor">
@ -225,7 +225,7 @@ If the JavaBean property is `foo` (or `Foo`), `<Get>` first attempts to invoke _
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<!-- Invokes getter method server.getVersion() -->
@ -252,7 +252,7 @@ If the JavaBean property is `foo` (or `Foo`), `<Set>` first attempts to invoke _
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<!-- The value in the <Set> scope is the string "true" -->
@ -277,7 +277,7 @@ The map entries are specified with a sequence of `<Entry>` elements, each with e
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Map class="java.util.concurrent.ConcurrentHashMap">
@ -302,7 +302,7 @@ You can only specify the key value via the `name` attribute, so the key can only
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<New class="java.util.Properties">
@ -323,7 +323,7 @@ Element `<Array>` creates a new array, whose component type may be specified by
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Array type="java.lang.Object">
@ -347,7 +347,7 @@ You must give a unique `id` attribute to the objects you want to reference.
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<!-- The Jetty Server has id="server" -->
<Configure id="server" class="org.eclipse.jetty.server.Server">
@ -381,7 +381,7 @@ For example, you may want to configure the context path of your web application
[source,xml,subs="verbatim,quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="contextPath">
@ -407,7 +407,7 @@ The following example creates a minimal Jetty `Server` that listens on a port sp
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Arg type="int">
@ -430,7 +430,7 @@ The following example creates a minimal Jetty `Server` that listens on a port sp
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Arg type="int">
@ -462,7 +462,7 @@ The following example illustrates how scopes work:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Arg type="int">8080</Arg>

View File

@ -40,7 +40,7 @@ Using the Jetty WebSocket APIs allows your applications to be more efficient and
If your application needs specific features that are not provided by the standard APIs, the Jetty WebSocket APIs may provide such features.
TIP: If the feature you are looking for is not present, you may ask for these features by link:https://github.com/eclipse/jetty.project/issues[submitting an issue] to the Jetty Project without waiting for the standard Jakarta EE process to approve them and release a new version of the Jakarta EE WebSocket specification.
TIP: If the feature you are looking for is not present, you may ask for these features by link:https://github.com/jetty/jetty.project/issues[submitting an issue] to the Jetty Project without waiting for the standard Jakarta EE process to approve them and release a new version of the Jakarta EE WebSocket specification.
include::server-websocket-standard.adoc[]
include::server-websocket-filter.adoc[]

View File

@ -3,7 +3,7 @@ version: '12'
title: Eclipse Jetty
asciidoc:
attributes:
javadoc-url: https://eclipse.dev/jetty/javadoc/jetty-12
javadoc-url: https://jetty.org/javadoc/jetty-12
jdurl: '{javadoc-url}'
jetty-home: ${jetty.home}@
version: 12.0.10-SNAPSHOT

View File

@ -27,6 +27,7 @@ import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.Trailers;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.server.Context;
@ -60,10 +61,11 @@ public class ServletToHandlerDocs
// - servletRequest.getProtocol();
String protocol = request.getConnectionMetaData().getProtocol();
// Gets the full request URI.
// Gets the request URL.
// Replaces:
// - servletRequest.getRequestURL();
String fullRequestURI = request.getHttpURI().asString();
HttpURI httpURI = HttpURI.build(request.getHttpURI()).query(null);
StringBuffer requestURL = new StringBuffer(httpURI.asString());
// Gets the request context.
// Replaces:

View File

@ -47,7 +47,7 @@ Here's an example context XML file that calls this method:
[,xml,subs=attributes+]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Set name="configurationDiscovered">false</Set> <!--2-->
@ -76,7 +76,7 @@ Here's an example from a context XML file that includes any jar whose name start
[,xml,subs=attributes+]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->
@ -107,7 +107,7 @@ Here's an example of a context XML file that sets a pattern that matches any jar
[,xml,subs=attributes+]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->
@ -173,7 +173,7 @@ Here's an example of setting the context attribute in a context XML file:
[,xml,subs=attributes+]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->
@ -204,7 +204,7 @@ Here is an example context XML file that ensures the `com.example.PrioritySCI` w
[,xml,subs=attributes+]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->

View File

@ -58,7 +58,7 @@ Read the xref:arch/index.adoc[Jetty architecture section] for more information a
[[download]]
== Downloading Jetty
The Jetty distribution is a file of the form `jetty-home-<version>.<ext>`, available for download from https://eclipse.dev/jetty/download.php[]
The Jetty distribution is a file of the form `jetty-home-<version>.<ext>`, available for download from https://jetty.org/download.html[]
The Jetty distribution is available in both `zip` and `gzip` formats; download the one most appropriate for your system, typically `zip` for Windows and `gzip` for other operating systems.

View File

@ -140,7 +140,7 @@ A simple Jetty context XML file, for example named `wiki.xml` is the following:
[,xml,subs=attributes+]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
<Set name="contextPath">/wiki</Set> <!--2-->
@ -185,7 +185,7 @@ You can use the features of xref:xml/index.adoc[Jetty XML files] to avoid to har
[,xml,subs=attributes+]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/wiki</Set>
@ -209,7 +209,7 @@ The JNDI entry must be _defined_ in a xref:jndi/index.adoc#xml[Jetty XML file],
[,xml,subs="attributes+,+quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="wac" class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/mywebapp</Set>
@ -282,7 +282,7 @@ If you have a web application `mywebapp.war` you can configure its virtual hosts
[,xml,subs=attributes+]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/mywebapp</Set>
@ -327,7 +327,7 @@ To achieve this, you simply use the same context path of `/` for each of your we
[,xml,subs=attributes+]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/</Set>
@ -344,7 +344,7 @@ To achieve this, you simply use the same context path of `/` for each of your we
[,xml,subs=attributes+]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/</Set>
@ -372,7 +372,7 @@ In this case, you want to xref:protocols/index.adoc[configure multiple connector
[,xml,subs="attributes+,+quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/</Set>
@ -389,7 +389,7 @@ In this case, you want to xref:protocols/index.adoc[configure multiple connector
[,xml,subs="attributes+,+quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/</Set>
@ -424,7 +424,7 @@ If you do not want Jetty to extract the `+*.war+` files, you can disable this fe
[,xml,subs="attributes+,+quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/mywebapp</Set>
@ -444,7 +444,7 @@ This allows you to add host specific configuration or server specific configurat
[,xml,subs="attributes+,+quotes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
<Set name="contextPath">/mywebapp</Set>

View File

@ -96,7 +96,7 @@ Here's an example of this type of XML file:
[,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addBean">
<Arg>
@ -114,7 +114,7 @@ Here's an example of this type of XML file:
[,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="securityHandler">
<New class="org.eclipse.jetty.security.ConstraintSecurityHandler">

View File

@ -26,7 +26,7 @@ Here's an example of using a context xml file to add in a pattern to match files
[,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
<Call name="setAttribute"> <!--2-->

View File

@ -42,7 +42,7 @@ Start with the custom Jetty XML file, `$JETTY_BASE/etc/custom-ssl.xml`:
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Ref refid="sslContextFactory"> <!--1-->
<Set name="CipherComparator"> <!--2-->
@ -158,7 +158,7 @@ Next, let's write the Jetty XML file that wires the auditing component to the `S
[,xml,options=nowrap]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Ref refid="Server"> <!--1-->
<Call name="insertHandler"> <!--2-->

View File

@ -84,7 +84,7 @@ For example, a Jetty XML file that allocates Jetty's `QueuedThreadPool` could be
.jetty-threadpool.xml
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<New id="threadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="maxThreads" type="int">
@ -234,7 +234,7 @@ The `custom-server.xml` file is the following:
[,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Server" class="com.acme.server.CustomJettyServer">
</Configure>
----

View File

@ -349,7 +349,7 @@ An example of `jetty-rewrite-rules.xml` is the following:
.jetty-rewrite-rules.xml
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
<Call name="addRule">
<!-- Redirect with a 301 from /old/* to /new/* -->
@ -371,7 +371,7 @@ In the example below, the rule will only be evaluated if the virtual host matche
.jetty-rewrite-rules.xml
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
<Call name="addRule">
<Arg>

View File

@ -616,7 +616,7 @@ Use the following file as example, copy it as `$JETTY_BASE/webapps/wordpress.xml
[,xml,options=nowrap]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
<New id="root" class="java.lang.String">
@ -740,7 +740,7 @@ You want to create the `$JETTY_BASE/etc/tls-config.xml` with the following templ
[,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Ref refid="sslContextFactory">
@ -766,7 +766,7 @@ To explicitly add the exclusion of TLSv1.0 and TLSv1.1 (that are also vulnerable
[,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Ref refid="sslContextFactory">
@ -791,7 +791,7 @@ You can precisely set the list of excluded ciphers, completely overriding Jetty'
[,xml]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Ref refid="sslContextFactory">

View File

@ -604,7 +604,7 @@ There are no configuration properties associated with this module.
From Jetty-9.4.13 onwards, we have changed the format of the serialized session when using a remote cache (ie using hotrod).
Prior to release 9.4.13 we used the default Infinispan serialization, however this was not able to store sufficient information to allow Jetty to properly deserialize session attributes in all circumstances.
See issue https://github.com/eclipse/jetty.project/issues/2919[] for more background.
See issue https://github.com/jetty/jetty.project/issues/2919[] for more background.
We have provided a conversion program which will convert any sessions stored in Infinispan to the new format.

View File

@ -31,7 +31,7 @@ The Jetty XML elements define attributes such as `id`, `name`, `class`, etc. tha
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Get id="stderr" class="java.lang.System" name="err">
@ -43,7 +43,7 @@ The Jetty XML elements define attributes such as `id`, `name`, `class`, etc. tha
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Get>
@ -70,7 +70,7 @@ The following Jetty XML creates an empty `String` and assigns it the id `mystrin
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="mystring" class="java.lang.String" />
----
@ -98,7 +98,7 @@ The following example creates a minimal Jetty `Server`:
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.server.Server">
<Arg type="int">8080</Arg>
@ -112,7 +112,7 @@ Arguments may also have a `name` attribute, which is matched with the correspond
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.server.Server">
<Arg name="port" type="int">8080</Arg>
@ -132,7 +132,7 @@ The following example creates an `ArrayList`:
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<New id="mylist" class="java.util.ArrayList">
@ -159,7 +159,7 @@ Within element `<Call>` the return value, if the return type is not `void`, is i
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<New class="java.util.ArrayList">
@ -183,7 +183,7 @@ It is possible to call `static` methods by specifying the `class` attribute:
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Call id="myhost" name="getByName" class="java.net.InetAddress">
@ -206,7 +206,7 @@ For example:
[,xml,subs=+quotes]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Call class="java.util.concurrent.Executors" name="newSingleThreadScheduledExecutor">
@ -235,7 +235,7 @@ If the JavaBean property is `foo` (or `Foo`), `<Get>` first attempts to invoke _
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<!-- Invokes getter method server.getVersion() -->
@ -262,7 +262,7 @@ If the JavaBean property is `foo` (or `Foo`), `<Set>` first attempts to invoke _
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<!-- The value in the <Set> scope is the string "true" -->
@ -287,7 +287,7 @@ The map entries are specified with a sequence of `<Entry>` elements, each with e
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Map class="java.util.concurrent.ConcurrentHashMap">
@ -312,7 +312,7 @@ You can only specify the key value via the `name` attribute, so the key can only
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<New class="java.util.Properties">
@ -333,7 +333,7 @@ Element `<Array>` creates a new array, whose component type may be specified by
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure>
<Array type="java.lang.Object">
@ -357,7 +357,7 @@ You must give a unique `id` attribute to the objects you want to reference.
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<!-- The Jetty Server has id="server" -->
<Configure id="server" class="org.eclipse.jetty.server.Server">
@ -391,7 +391,7 @@ For example, you may want to configure the context path of your web application
[,xml,subs=+quotes]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="contextPath">
@ -417,7 +417,7 @@ The following example creates a minimal Jetty `Server` that listens on a port sp
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Arg type="int">
@ -440,7 +440,7 @@ The following example creates a minimal Jetty `Server` that listens on a port sp
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Arg type="int">
@ -472,7 +472,7 @@ The following example illustrates how scopes work:
[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Arg type="int">8080</Arg>

View File

@ -47,37 +47,46 @@ Use an editor to create the file `src/main/java/org/example/HelloWorld.java` wit
----
package org.example;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletException;
import java.io.IOException;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;
public class HelloWorld extends AbstractHandler
class HelloWorldHandler extends Handler.Abstract.NonBlocking
{
public void handle(String target,
Request baseRequest,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
@Override
public boolean handle(Request request, Response response, Callback callback)
{
response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
response.getWriter().println("<h1>Hello World</h1>");
}
response.setStatus(200);
response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/html; charset=UTF-8");
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
server.setHandler(new HelloWorld());
server.start();
server.join();
// Write a Hello World response.
Content.Sink.write(response, true, """
<!DOCTYPE html>
<html>
<head>
<title>Jetty Hello World Handler</title>
</head>
<body>
<p>Hello World</p>
</body>
</html>
""", callback);
return true;
}
}
Server server = new Server();
Connector connector = new ServerConnector(server);
server.addConnector(connector);
// Set the Hello World Handler.
server.setHandler(new HelloWorldHandler());
server.start();
}
----
[[creating-embedded-pom-descriptor]]
@ -116,7 +125,6 @@ Use an editor to create the file `pom.xml` in the `JettyMavenHelloWorld` directo
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution><goals><goal>java</goal></goals></execution>
</executions>

View File

@ -39,7 +39,7 @@ Using the Jetty WebSocket APIs allows your applications to be more efficient and
If your application needs specific features that are not provided by the standard APIs, the Jetty WebSocket APIs may provide such features.
TIP: If the feature you are looking for is not present, you may ask for these features by https://github.com/eclipse/jetty.project/issues[submitting an issue] to the Jetty Project without waiting for the standard Jakarta EE process to approve them and release a new version of the Jakarta EE WebSocket specification.
TIP: If the feature you are looking for is not present, you may ask for these features by https://github.com/jetty/jetty.project/issues[submitting an issue] to the Jetty Project without waiting for the standard Jakarta EE process to approve them and release a new version of the Jakarta EE WebSocket specification.
[[standard]]
== Standard APIs Implementation

View File

@ -21,6 +21,7 @@ import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -243,6 +244,7 @@ public class ContextProvider extends ScanningAppProvider
/**
* This is equivalent to setting the {@link Deployable#CONFIGURATION_CLASSES} property.
*
* @param configurations The configuration class names as a comma separated list
*/
public void setConfigurationClasses(String configurations)
@ -252,6 +254,7 @@ public class ContextProvider extends ScanningAppProvider
/**
* This is equivalent to setting the {@link Deployable#CONFIGURATION_CLASSES} property.
*
* @param configurations The configuration class names.
*/
public void setConfigurationClasses(String[] configurations)
@ -262,8 +265,8 @@ public class ContextProvider extends ScanningAppProvider
}
/**
*
* This is equivalent to getting the {@link Deployable#CONFIGURATION_CLASSES} property.
*
* @return The configuration class names.
*/
@ManagedAttribute("configuration classes for webapps to be processed through")
@ -341,32 +344,48 @@ public class ContextProvider extends ScanningAppProvider
// prepare properties
Map<String, String> properties = new HashMap<>();
//add in properties from start mechanism
properties.putAll(getProperties());
Object context = null;
//check if there is a specific ContextHandler type to create set in the
//properties associated with the webapp. If there is, we create it _before_
//applying the environment xml file.
String contextHandlerClassName = app.getProperties().get(Deployable.CONTEXT_HANDLER_CLASS);
if (contextHandlerClassName != null)
context = Class.forName(contextHandlerClassName).getDeclaredConstructor().newInstance();
//add in environment-specific properties
String env = app.getEnvironmentName() == null ? "" : app.getEnvironmentName();
Path envProperties = app.getPath().getParent().resolve(env + ".properties");
if (Files.exists(envProperties))
{
try (InputStream stream = Files.newInputStream(envProperties))
{
Properties p = new Properties();
p.load(stream);
p.stringPropertyNames().forEach(k -> properties.put(k, p.getProperty(k)));
}
String str = properties.get(Deployable.ENVIRONMENT_XML);
if (!StringUtil.isEmpty(str))
{
Path envXmlPath = Paths.get(str);
if (!envXmlPath.isAbsolute())
envXmlPath = getMonitoredDirResource().getPath().getParent().resolve(envXmlPath);
context = applyXml(context, envXmlPath, env, properties);
}
}
//add in properties specific to the deployable
properties.putAll(app.getProperties());
// Handle a context XML file
if (FileID.isXml(path))
{
XmlConfiguration xmlc = new XmlConfiguration(ResourceFactory.of(this).newResource(path), null, properties)
{
@Override
public void initializeDefaults(Object context)
{
super.initializeDefaults(context);
ContextProvider.this.initializeContextHandler(context, path, properties);
}
};
xmlc.getIdMap().put("Environment", environment);
xmlc.setJettyStandardIdsAndProperties(getDeploymentManager().getServer(), path);
// If it is a core context environment, then look for a classloader
ClassLoader coreContextClassLoader = Environment.CORE.equals(environment) ? findCoreContextClassLoader(path) : null;
if (coreContextClassLoader != null)
Thread.currentThread().setContextClassLoader(coreContextClassLoader);
// Create the context by running the configuration
Object context = xmlc.configure();
context = applyXml(context, path, env, properties);
// Look for the contextHandler itself
ContextHandler contextHandler = null;
@ -382,27 +401,33 @@ public class ContextProvider extends ScanningAppProvider
throw new IllegalStateException("Unknown context type of " + context);
// Set the classloader if we have a coreContextClassLoader
ClassLoader coreContextClassLoader = Environment.CORE.equals(environment) ? findCoreContextClassLoader(path) : null;
if (coreContextClassLoader != null)
contextHandler.setClassLoader(coreContextClassLoader);
return contextHandler;
}
// Otherwise it must be a directory or an archive
else if (!Files.isDirectory(path) && !FileID.isWebArchive(path))
{
throw new IllegalStateException("unable to create ContextHandler for " + app);
}
// Build the web application
String contextHandlerClassName = (String)environment.getAttribute("contextHandlerClass");
// Build the web application if necessary
if (context == null)
{
contextHandlerClassName = (String)environment.getAttribute("contextHandlerClass");
if (StringUtil.isBlank(contextHandlerClassName))
throw new IllegalStateException("No ContextHandler classname for " + app);
Class<?> contextHandlerClass = Loader.loadClass(contextHandlerClassName);
if (contextHandlerClass == null)
throw new IllegalStateException("Unknown ContextHandler class " + contextHandlerClassName + " for " + app);
Object context = contextHandlerClass.getDeclaredConstructor().newInstance();
context = contextHandlerClass.getDeclaredConstructor().newInstance();
properties.put(Deployable.WAR, path.toString());
}
return initializeContextHandler(context, path, properties);
}
finally
@ -411,6 +436,36 @@ public class ContextProvider extends ScanningAppProvider
}
}
protected Object applyXml(Object context, Path xml, String environment, Map<String, String> properties) throws Exception
{
if (!FileID.isXml(xml))
return null;
XmlConfiguration xmlc = new XmlConfiguration(ResourceFactory.of(this).newResource(xml), null, properties)
{
@Override
public void initializeDefaults(Object context)
{
super.initializeDefaults(context);
ContextProvider.this.initializeContextHandler(context, xml, properties);
}
};
xmlc.getIdMap().put("Environment", environment);
xmlc.setJettyStandardIdsAndProperties(getDeploymentManager().getServer(), xml);
// If it is a core context environment, then look for a classloader
ClassLoader coreContextClassLoader = Environment.CORE.equals(environment) ? findCoreContextClassLoader(xml) : null;
if (coreContextClassLoader != null)
Thread.currentThread().setContextClassLoader(coreContextClassLoader);
// Create or configure the context
if (context == null)
return xmlc.configure();
return xmlc.configure(context);
}
protected ClassLoader findCoreContextClassLoader(Path path) throws IOException
{
Path webapps = path.getParent();

View File

@ -0,0 +1,20 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.deploy;
import org.eclipse.jetty.server.handler.ContextHandler;
public class BarContextHandler extends ContextHandler
{
}

View File

@ -15,27 +15,18 @@ package org.eclipse.jetty.deploy.providers;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import org.eclipse.jetty.deploy.AppProvider;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.BarContextHandler;
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.Deployable;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenPaths;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.component.Container;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.resource.Resource;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -43,6 +34,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -77,7 +69,10 @@ public class ContextProviderStartupTest
// Should not throw an Exception
jetty.load();
}
public void startJetty() throws Exception
{
// Start it
jetty.start();
}
@ -89,9 +84,47 @@ public class ContextProviderStartupTest
}
@Test
public void testStartupContext()
public void testStartupContext() throws Exception
{
startJetty();
// Check Server for Handlers
jetty.assertContextHandlerExists("/bar");
}
@Test
public void testStartupWithRelativeEnvironmentContext() throws Exception
{
Path jettyBase = jetty.getJettyBasePath();
Path propsFile = Files.writeString(jettyBase.resolve("webapps/core.properties"), Deployable.ENVIRONMENT_XML + " = etc/core-context.xml", StandardOpenOption.CREATE_NEW);
assertTrue(Files.exists(propsFile));
Files.copy(MavenPaths.findTestResourceFile("etc/core-context.xml"), jettyBase.resolve("etc/core-context.xml"), StandardCopyOption.REPLACE_EXISTING);
jetty.copyWebapp("bar-core-context.properties", "bar.properties");
startJetty();
//check environment context xml was applied to the produced context
ContextHandler context = jetty.getContextHandler("/bar");
assertNotNull(context);
assertThat(context.getAttribute("somename"), equalTo("somevalue"));
assertTrue(context instanceof BarContextHandler);
}
@Test
public void testStartupWithAbsoluteEnvironmentContext() throws Exception
{
Path jettyBase = jetty.getJettyBasePath();
Path propsFile = Files.writeString(jettyBase.resolve("webapps/core.properties"), Deployable.ENVIRONMENT_XML + " = " +
MavenPaths.findTestResourceFile("etc/core-context.xml"), StandardOpenOption.CREATE_NEW);
assertTrue(Files.exists(propsFile));
Files.copy(MavenPaths.findTestResourceFile("etc/core-context.xml"), jettyBase.resolve("etc/core-context.xml"), StandardCopyOption.REPLACE_EXISTING);
jetty.copyWebapp("bar-core-context.properties", "bar-core-context.properties");
startJetty();
//check environment context xml was applied to the produced context
ContextHandler context = jetty.getContextHandler("/bar");
assertNotNull(context);
assertThat(context.getAttribute("somename"), equalTo("somevalue"));
}
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- // -->
<!-- // ======================================================================== -->
<!-- // Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -->
<!-- // -->
<!-- // This program and the accompanying materials are made available under the -->
<!-- // terms of the Eclipse Public License v. 2.0 which is available at -->
<!-- // https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -->
<!-- // which is available at https://www.apache.org/licenses/LICENSE-2.0. -->
<!-- // -->
<!-- // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -->
<!-- // ======================================================================== -->
<!-- // -->
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="contextPath">/global</Set>
<Call name="setAttribute">
<Arg>somename</Arg>
<Arg>somevalue</Arg>
</Call>
</Configure>

View File

@ -0,0 +1,2 @@
environment: core
jetty.deploy.contextHandlerClass: org.eclipse.jetty.deploy.BarContextHandler

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call class="org.eclipse.jetty.ee.WebAppClassLoading" name="addProtectedClasses">

View File

@ -169,9 +169,7 @@ public class WebAppClassLoading
* Add a hidden (server) Class pattern to use for all WebAppContexts of a given {@link Server}.
* @param attributes The {@link Attributes} instance to add classes to
* @param patterns the patterns to use
* @deprecated use {@link #addHiddenClasses(Server, String...)} instead
*/
@Deprecated (since = "12.0.9", forRemoval = true)
public static void addHiddenClasses(Attributes attributes, String... patterns)
{
if (patterns != null && patterns.length > 0)

View File

@ -38,9 +38,16 @@ import java.util.stream.StreamSupport;
/**
* <p>An ordered collection of {@link HttpField}s that represent the HTTP headers
* or HTTP trailers of an HTTP request or an HTTP response.</p>
*
* <p>{@link HttpFields} is immutable and typically used in server-side HTTP requests
* and client-side HTTP responses, while {@link HttpFields.Mutable} is mutable and
* typically used in server-side HTTP responses and client-side HTTP requests.</p>
*
* <p>Access is always more efficient using {@link HttpHeader} keys rather than {@link String} field names.</p>
*
* <p>The primary implementations of {@code HttpFields} have been optimized assuming few
* lookup operations, thus typically if many {@link HttpField}s need to looked up, it may be
* better to use an {@link Iterator} to find multiple fields in a single iteration.</p>
*/
public interface HttpFields extends Iterable<HttpField>, Supplier<HttpFields>
{
@ -350,10 +357,12 @@ public interface HttpFields extends Iterable<HttpField>, Supplier<HttpFields>
/**
* <p>Returns whether this instance contains the given field name.</p>
* <p>The comparison of field name is case-insensitive via
* {@link HttpField#is(String)}.
* {@link HttpField#is(String)}. If possible, it is more efficient to use
* {@link #contains(HttpHeader)}.
*
* @param name the case-insensitive field name to search for
* @return whether this instance contains the given field name
* @see #contains(HttpHeader)
*/
default boolean contains(String name)
{
@ -412,7 +421,7 @@ public interface HttpFields extends Iterable<HttpField>, Supplier<HttpFields>
* <p>Returns the encoded value of the first field with the given field name,
* or {@code null} if no such field is present.</p>
* <p>The comparison of field name is case-insensitive via
* {@link HttpField#is(String)}.</p>
* {@link HttpField#is(String)}. If possible, it is more efficient to use {@link #get(HttpHeader)}.</p>
* <p>In case of multi-valued fields, the returned value is the encoded
* value, including commas and quotes, as returned by {@link HttpField#getValue()}.</p>
*
@ -420,6 +429,7 @@ public interface HttpFields extends Iterable<HttpField>, Supplier<HttpFields>
* @return the raw value of the first field with the given field name,
* or {@code null} if no such field is present
* @see HttpField#getValue()
* @see #get(HttpHeader)
*/
default String get(String name)
{
@ -594,12 +604,13 @@ public interface HttpFields extends Iterable<HttpField>, Supplier<HttpFields>
* <p>Returns a {@link Set} of the field names.</p>
* <p>Case-sensitivity of the field names is preserved.</p>
*
* @return a {@link Set} of the field names
* @return an immutable {@link Set} of the field names. Changes made to the
* {@code HttpFields} after this call are not reflected in the set.
*/
default Set<String> getFieldNamesCollection()
{
Set<HttpHeader> seenByHeader = EnumSet.noneOf(HttpHeader.class);
Set<String> seenByName = null;
Set<String> buildByName = null;
List<String> list = new ArrayList<>(size());
for (HttpField f : this)
@ -607,9 +618,9 @@ public interface HttpFields extends Iterable<HttpField>, Supplier<HttpFields>
HttpHeader header = f.getHeader();
if (header == null)
{
if (seenByName == null)
seenByName = new TreeSet<>(String::compareToIgnoreCase);
if (seenByName.add(f.getName()))
if (buildByName == null)
buildByName = new TreeSet<>(String::compareToIgnoreCase);
if (buildByName.add(f.getName()))
list.add(f.getName());
}
else if (seenByHeader.add(header))
@ -618,6 +629,8 @@ public interface HttpFields extends Iterable<HttpField>, Supplier<HttpFields>
}
}
Set<String> seenByName = buildByName;
// use the list to retain a rough ordering
return new AbstractSet<>()
{
@ -632,6 +645,14 @@ public interface HttpFields extends Iterable<HttpField>, Supplier<HttpFields>
{
return list.size();
}
@Override
public boolean contains(Object o)
{
if (o instanceof String s)
return seenByName != null && seenByName.contains(s) || seenByHeader.contains(HttpHeader.CACHE.get(s));
return false;
}
};
}

View File

@ -20,12 +20,7 @@ import java.util.Objects;
import java.util.stream.Stream;
/**
* HTTP Fields. A collection of HTTP header and or Trailer fields.
*
* <p>This class is not synchronized as it is expected that modifications will only be performed by a
* single thread.
*
* <p>The cookie handling provided by this class is guided by the Servlet specification and RFC6265.
* An immutable implementation of {@link HttpFields}.
*/
class ImmutableHttpFields implements HttpFields
{
@ -70,10 +65,9 @@ class ImmutableHttpFields implements HttpFields
{
if (this == o)
return true;
if (!(o instanceof org.eclipse.jetty.http.ImmutableHttpFields))
if (o instanceof HttpFields httpFields)
return isEqualTo(httpFields);
return false;
return isEqualTo((HttpFields)o);
}
@Override

View File

@ -67,7 +67,7 @@ class MutableHttpFields implements HttpFields.Mutable
*/
protected MutableHttpFields(HttpFields fields)
{
if (fields instanceof ImmutableHttpFields immutable)
if (fields instanceof org.eclipse.jetty.http.ImmutableHttpFields immutable)
{
_immutable = true;
_fields = immutable._fields;
@ -180,7 +180,7 @@ class MutableHttpFields implements HttpFields.Mutable
public HttpFields asImmutable()
{
_immutable = true;
return new ImmutableHttpFields(_fields, _size);
return new org.eclipse.jetty.http.ImmutableHttpFields(_fields, _size);
}
private void copyImmutable()

View File

@ -25,6 +25,7 @@ import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -352,16 +353,27 @@ public class HttpFieldsTest
assertThat(header.get("EXPECT"), is("100"));
assertThat(header.get("eXpEcT"), is("100"));
assertThat(header.get(HttpHeader.EXPECT), is("100"));
assertTrue(header.contains("expect"));
assertTrue(header.contains("Expect"));
assertTrue(header.contains("EXPECT"));
assertTrue(header.contains("eXpEcT"));
assertThat(header.get("random"), is("value"));
assertThat(header.get("Random"), is("value"));
assertThat(header.get("RANDOM"), is("value"));
assertThat(header.get("rAnDoM"), is("value"));
assertThat(header.get("RaNdOm"), is("value"));
assertTrue(header.contains("random"));
assertTrue(header.contains("Random"));
assertTrue(header.contains("RANDOM"));
assertTrue(header.contains("rAnDoM"));
assertTrue(header.contains("RaNdOm"));
assertThat(header.get("Accept-Charset"), is("UTF-8"));
assertThat(header.get("accept-charset"), is("UTF-8"));
assertThat(header.get(HttpHeader.ACCEPT_CHARSET), is("UTF-8"));
assertTrue(header.contains("Accept-Charset"));
assertTrue(header.contains("accept-charset"));
assertThat(header.getValuesList("Accept-Charset"), contains("UTF-8", "UTF-16"));
assertThat(header.getValuesList("accept-charset"), contains("UTF-8", "UTF-16"));
@ -371,9 +383,19 @@ public class HttpFieldsTest
assertThat(header.get("Foo-Bar"), is("one"));
assertThat(header.getValuesList("foo-bar"), contains("one", "two"));
assertThat(header.getValuesList("Foo-Bar"), contains("one", "two"));
assertTrue(header.contains("foo-bar"));
assertTrue(header.contains("Foo-Bar"));
// We know the order of the set is deterministic
assertThat(header.getFieldNamesCollection(), contains("expect", "RaNdOm", "Accept-Charset", "foo-bar"));
Set<String> names = header.getFieldNamesCollection();
assertThat(names, contains("expect", "RaNdOm", "Accept-Charset", "foo-bar"));
assertTrue(names.contains("expect"));
assertTrue(names.contains("Expect"));
assertTrue(names.contains("random"));
assertTrue(names.contains("accept-charset"));
assertTrue(names.contains("Accept-Charset"));
assertTrue(names.contains("foo-bar"));
assertTrue(names.contains("Foo-Bar"));
}
@ParameterizedTest

View File

@ -13,6 +13,7 @@
package org.eclipse.jetty.http2.server;
import java.io.EOFException;
import java.util.Map;
import java.util.concurrent.TimeoutException;
@ -155,7 +156,7 @@ public class HTTP2ServerConnectionFactory extends AbstractHTTP2ServerConnectionF
@Override
public void onReset(Stream stream, ResetFrame frame, Callback callback)
{
EofException failure = new EofException("Reset " + ErrorCode.toString(frame.getError(), null));
EOFException failure = new EOFException("Reset " + ErrorCode.toString(frame.getError(), null));
onFailure(stream, failure, callback);
}

View File

@ -13,6 +13,7 @@
package org.eclipse.jetty.http2.server.internal;
import java.io.EOFException;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeoutException;
import java.util.function.BiConsumer;
@ -38,6 +39,7 @@ import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpStream;
import org.eclipse.jetty.server.Request;
@ -587,7 +589,8 @@ public class HttpStreamOverHTTP2 implements HttpStream, HTTP2Channel.Server
@Override
public Runnable onFailure(Throwable failure, Callback callback)
{
Runnable runnable = _httpChannel.onFailure(failure);
boolean remote = failure instanceof EOFException;
Runnable runnable = remote ? _httpChannel.onRemoteFailure(new EofException(failure)) : _httpChannel.onFailure(failure);
return () ->
{
if (runnable != null)

View File

@ -58,7 +58,12 @@ public class AbstractTest
protected void start(Handler handler) throws Exception
{
HTTP2CServerConnectionFactory connectionFactory = new HTTP2CServerConnectionFactory(new HttpConfiguration());
start(handler, new HttpConfiguration());
}
protected void start(Handler handler, HttpConfiguration httpConfiguration) throws Exception
{
HTTP2CServerConnectionFactory connectionFactory = new HTTP2CServerConnectionFactory(httpConfiguration);
connectionFactory.setInitialSessionRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
connectionFactory.setInitialStreamRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
prepareServer(connectionFactory);

View File

@ -17,22 +17,33 @@ import java.io.InterruptedIOException;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.ErrorCode;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@ -241,6 +252,67 @@ public class AsyncIOTest extends AbstractTest
*/
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void testClientResetRemoteErrorNotification(boolean notify) throws Exception
{
CountDownLatch latch = new CountDownLatch(1);
AtomicReference<Response> responseRef = new AtomicReference<>();
AtomicReference<Throwable> failureRef = new AtomicReference<>();
HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.setNotifyRemoteAsyncErrors(notify);
start(new Handler.Abstract()
{
@Override
public boolean handle(Request request, Response response, Callback callback)
{
request.addFailureListener(failureRef::set);
responseRef.set(response);
latch.countDown();
return true;
}
}, httpConfiguration);
Session session = newClientSession(new Session.Listener() {});
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
HeadersFrame frame = new HeadersFrame(metaData, null, true);
FuturePromise<Stream> promise = new FuturePromise<>();
session.newStream(frame, promise, null);
Stream stream = promise.get(5, TimeUnit.SECONDS);
// Wait for the server to be idle.
assertTrue(latch.await(5, TimeUnit.SECONDS));
sleep(500);
stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP);
if (notify)
// Wait for the reset to be notified to the failure listener.
await().atMost(5, TimeUnit.SECONDS).until(failureRef::get, instanceOf(EofException.class));
else
// Wait for the reset to NOT be notified to the failure listener.
await().atMost(5, TimeUnit.SECONDS).during(1, TimeUnit.SECONDS).until(failureRef::get, nullValue());
// Assert that writing to the response fails.
var cb = new Callback()
{
private Throwable failure = null;
@Override
public void failed(Throwable x)
{
failure = x;
}
Throwable failure()
{
return failure;
}
};
responseRef.get().write(true, BufferUtil.EMPTY_BUFFER, cb);
await().atMost(5, TimeUnit.SECONDS).until(cb::failure, instanceOf(EofException.class));
}
private static void sleep(long ms) throws InterruptedIOException
{
try

View File

@ -154,58 +154,6 @@ public class AsyncServletTest extends AbstractTest
// assertTrue(clientLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
// }
//
// @Test
// public void testStartAsyncThenClientResetWithoutRemoteErrorNotification() throws Exception
// {
// HttpConfiguration httpConfiguration = new HttpConfiguration();
// httpConfiguration.setNotifyRemoteAsyncErrors(false);
// prepareServer(new HTTP2ServerConnectionFactory(httpConfiguration));
// ServletContextHandler context = new ServletContextHandler(server, "/");
// AtomicReference<AsyncContext> asyncContextRef = new AtomicReference<>();
// CountDownLatch latch = new CountDownLatch(1);
// context.addServlet(new ServletHolder(new HttpServlet()
// {
// @Override
// protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
// {
// AsyncContext asyncContext = request.startAsync();
// asyncContext.setTimeout(0);
// asyncContextRef.set(asyncContext);
// latch.countDown();
// }
// }), servletPath + "/*");
// server.start();
//
// prepareClient();
// client.start();
// Session session = newClient(new Session.Listener() {});
// MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
// HeadersFrame frame = new HeadersFrame(metaData, null, true);
// FuturePromise<Stream> promise = new FuturePromise<>();
// session.newStream(frame, promise, null);
// Stream stream = promise.get(5, TimeUnit.SECONDS);
//
// // Wait for the server to be in ASYNC_WAIT.
// assertTrue(latch.await(5, TimeUnit.SECONDS));
// sleep(500);
//
// stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP);
//
// // Wait for the reset to be processed by the server.
// sleep(500);
//
// AsyncContext asyncContext = asyncContextRef.get();
// ServletResponse response = asyncContext.getResponse();
// ServletOutputStream output = response.getOutputStream();
//
// assertThrows(IOException.class,
// () ->
// {
// // Large writes or explicit flush() must
// // fail because the stream has been reset.
// output.flush();
// });
// }
//
// @Test
// public void testStartAsyncThenServerSessionIdleTimeout() throws Exception

View File

@ -14,7 +14,6 @@
package org.eclipse.jetty.http3;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
@ -275,7 +274,7 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
}
}
private MessageParser.Result parseAndFill(boolean setFillInterest)
private MessageParser.Result parseAndFill(boolean setFillInterest) throws IOException
{
try
{
@ -336,17 +335,10 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
}
}
private int fill(ByteBuffer byteBuffer)
{
try
private int fill(ByteBuffer byteBuffer) throws IOException
{
return getEndPoint().fill(byteBuffer);
}
catch (IOException x)
{
throw new UncheckedIOException(x.getMessage(), x);
}
}
private void processHeaders(HeadersFrame frame, boolean wasBlocked, Runnable delegate)
{

View File

@ -13,6 +13,7 @@
package org.eclipse.jetty.http3.server.internal;
import java.io.EOFException;
import java.nio.ByteBuffer;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeoutException;
@ -33,6 +34,7 @@ import org.eclipse.jetty.http3.api.Stream;
import org.eclipse.jetty.http3.frames.DataFrame;
import org.eclipse.jetty.http3.frames.HeadersFrame;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpStream;
import org.eclipse.jetty.server.Request;
@ -536,6 +538,8 @@ public class HttpStreamOverHTTP3 implements HttpStream
chunk = Content.Chunk.from(failure, true);
}
connection.onFailure(failure);
return httpChannel.onFailure(failure);
boolean remote = failure instanceof EOFException;
return remote ? httpChannel.onRemoteFailure(new EofException(failure)) : httpChannel.onFailure(failure);
}
}

View File

@ -41,6 +41,11 @@
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.reactivestreams</groupId>
<artifactId>reactive-streams-tck-flow</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
@ -50,6 +55,22 @@
<argLine>@{argLine} ${jetty.surefire.argLine}
--add-reads org.eclipse.jetty.io=org.eclipse.jetty.logging</argLine>
</configuration>
<dependencies>
<!--
surefire plugin currently does not support junit5 with testng out of the box: https://maven.apache.org/surefire/maven-surefire-plugin/examples/testng.html#running-testng-and-junit-tests
We need to specify providers explicitly: https://maven.apache.org/surefire/maven-surefire-plugin/examples/providers.html
-->
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit-platform</artifactId>
<version>${maven.surefire.plugin.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-testng</artifactId>
<version>${maven.surefire.plugin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

View File

@ -13,11 +13,17 @@
package org.eclipse.jetty.io.content;
import java.util.Objects;
import java.util.concurrent.Flow;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.util.IteratingCallback;
import org.eclipse.jetty.util.MathUtils;
import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.StaticException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>Wraps a {@link Content.Source} as a {@link Flow.Publisher}.
@ -25,135 +31,282 @@ import org.eclipse.jetty.util.thread.AutoLock;
* read from the passed {@link Content.Source} and passed to {@link Flow.Subscriber#onNext(Object)}.
* If no content is available, then the {@link Content.Source#demand(Runnable)} method is used to
* ultimately call {@link Flow.Subscriber#onNext(Object)} once content is available.</p>
* <p>{@link Content.Source} can be consumed only once and does not support multicast subscription.
* {@link Content.Source} will be consumed fully, otherwise will be failed in case of any errors
* to prevent resource leaks.</p>
*/
public class ContentSourcePublisher implements Flow.Publisher<Content.Chunk>
{
private final Content.Source content;
private static final Logger LOG = LoggerFactory.getLogger(ContentSourcePublisher.class);
private final AtomicReference<Content.Source> content;
public ContentSourcePublisher(Content.Source content)
{
this.content = content;
Objects.requireNonNull(content, "Content.Source must not be null");
this.content = new AtomicReference<>(content);
}
@Override
public void subscribe(Flow.Subscriber<? super Content.Chunk> subscriber)
{
subscriber.onSubscribe(new SubscriptionImpl(content, subscriber));
// As per rule 1.11, we have decided to support SINGLE subscriber
// in a UNICAST configuration for this implementation. It means
// that Content.Source can be consumed only once.
Content.Source content = this.content.getAndSet(null);
if (content != null)
onSubscribe(subscriber, content);
else
onMultiSubscribe(subscriber);
}
private static class SubscriptionImpl implements Flow.Subscription
private void onSubscribe(Flow.Subscriber<? super Content.Chunk> subscriber, Content.Source content)
{
private final AutoLock lock = new AutoLock();
private final Content.Source content;
private final Flow.Subscriber<? super Content.Chunk> subscriber;
private long demand;
private boolean stalled;
private boolean cancelled;
private boolean terminated;
public SubscriptionImpl(Content.Source content, Flow.Subscriber<? super Content.Chunk> subscriber)
// As per rule 1.9, we need to throw a `java.lang.NullPointerException`
// if the `Subscriber` is `null`
if (subscriber == null)
{
this.content = content;
this.subscriber = subscriber;
this.stalled = true;
NullPointerException error = new NullPointerException("Flow.Subscriber must not be null");
content.fail(error);
throw error;
}
ActiveSubscription subscription = new ActiveSubscription(content, subscriber);
// As per rule 1.9, this method must return normally (i.e. not throw).
try
{
subscriber.onSubscribe(subscription);
}
catch (Throwable err)
{
// As per rule 2.13, we MUST consider subscription cancelled and
// MUST raise this error condition in a fashion that is adequate for the runtime environment.
subscription.cancel(new SuppressedException(err));
if (LOG.isTraceEnabled())
LOG.trace("Flow.Subscriber " + subscriber + " violated rule 2.13", err);
}
}
private void onMultiSubscribe(Flow.Subscriber<? super Content.Chunk> subscriber)
{
// As per rule 1.9, we need to throw a `java.lang.NullPointerException`
// if the `Subscriber` is `null`
if (subscriber == null)
throw new NullPointerException("Flow.Subscriber must not be null");
ExhaustedSubscription subscription = new ExhaustedSubscription();
// As per 1.9, this method must return normally (i.e. not throw).
try
{
// As per rule 1.9, the only legal way to signal about Subscriber rejection
// is by calling onError (after calling onSubscribe).
subscriber.onSubscribe(subscription);
subscriber.onError(new IllegalStateException("Content.Source was exhausted."));
}
catch (Throwable err)
{
// As per rule 2.13, we MUST consider subscription cancelled and
// MUST raise this error condition in a fashion that is adequate for the runtime environment.
if (LOG.isTraceEnabled())
LOG.trace("Flow.Subscriber " + subscriber + " violated rule 2.13", err);
}
}
private static final class ExhaustedSubscription implements Flow.Subscription
{
@Override
public void request(long n)
{
boolean process = false;
Throwable failure = null;
try (AutoLock ignored = lock.lock())
{
if (cancelled || terminated)
return;
if (n <= 0)
{
terminated = true;
failure = new IllegalArgumentException("invalid demand " + n);
}
demand = MathUtils.cappedAdd(demand, n);
if (stalled)
{
stalled = false;
process = true;
}
}
if (failure != null)
subscriber.onError(failure);
else if (process)
process();
// As per rules 3.6 and 3.7, after the Subscription is cancelled all operations MUST be NOPs.
}
@Override
public void cancel()
{
try (AutoLock ignored = lock.lock())
{
cancelled = true;
// As per rules 3.6 and 3.7, after the Subscription is cancelled all operations MUST be NOPs.
}
}
private void process()
private static final class ActiveSubscription extends IteratingCallback implements Flow.Subscription
{
while (true)
private static final long NO_MORE_DEMAND = -1;
private static final Throwable COMPLETED = new StaticException("Source.Content read fully");
private final AtomicReference<Throwable> cancelled;
private final AtomicLong demand;
private Content.Source content;
private Flow.Subscriber<? super Content.Chunk> subscriber;
public ActiveSubscription(Content.Source content, Flow.Subscriber<? super Content.Chunk> subscriber)
{
try (AutoLock ignored = lock.lock())
{
if (demand > 0)
{
--demand;
this.cancelled = new AtomicReference<>(null);
this.demand = new AtomicLong(0);
this.content = content;
this.subscriber = subscriber;
}
else
// As per rule 3.3, Subscription MUST place an upper bound on possible synchronous
// recursion between Publisher and Subscriber
//
// As per rule 1.3, onSubscribe, onNext, onError and onComplete signaled to a
// Subscriber MUST be signaled serially.
//
// IteratingCallback guarantee that process() method will be executed by one thread only.
// The process() method can be only initiated from request() or cancel() demands methods.
@Override
protected Action process()
{
stalled = true;
return;
Throwable cancelled = this.cancelled.get();
if (cancelled != null)
{
// As per rule 3.13, Subscription.cancel() MUST request the Publisher to eventually
// drop any references to the corresponding subscriber.
this.demand.set(NO_MORE_DEMAND);
if (cancelled != COMPLETED)
this.content.fail(cancelled);
this.content = null;
try
{
if (cancelled == COMPLETED)
this.subscriber.onComplete();
else if (!(cancelled instanceof SuppressedException))
this.subscriber.onError(cancelled);
}
catch (Throwable err)
{
if (LOG.isTraceEnabled())
LOG.trace("Flow.Subscriber " + subscriber + " violated rule 2.13", err);
}
this.subscriber = null;
return Action.SUCCEEDED;
}
Content.Chunk chunk = content.read();
if (chunk == null)
{
try (AutoLock ignored = lock.lock())
{
// Restore the demand decremented above.
++demand;
stalled = true;
}
content.demand(this::process);
return;
content.demand(this::succeeded);
return Action.SCHEDULED;
}
if (Content.Chunk.isFailure(chunk))
{
terminate();
if (!chunk.isLast())
content.fail(chunk.getFailure());
subscriber.onError(chunk.getFailure());
return;
cancel(chunk.getFailure());
chunk.release();
return Action.IDLE;
}
subscriber.onNext(chunk);
try
{
this.subscriber.onNext(chunk);
}
catch (Throwable err)
{
cancel(new SuppressedException(err));
if (LOG.isTraceEnabled())
LOG.trace("Flow.Subscriber " + subscriber + " violated rule 2.13", err);
}
chunk.release();
if (chunk.isLast())
{
terminate();
// Reactive Stream specification rule 2.9 allows Publishers to call onComplete()
// even without demand, and Subscribers must be prepared to handle this case.
subscriber.onComplete();
cancel(COMPLETED);
return Action.IDLE;
}
if (demand.decrementAndGet() > 0)
this.iterate();
return Action.IDLE;
}
@Override
public void request(long n)
{
// As per rules 3.6 and 3.7, after the Subscription is cancelled all operations MUST be NOPs.
if (cancelled.get() != null)
return;
// As per rule 3.9, MUST signal onError with a java.lang.IllegalArgumentException if the argument is <= 0.
if (n <= 0L)
{
String errorMsg = "Flow.Subscriber " + subscriber + " violated rule 3.9: non-positive requests are not allowed.";
cancel(new IllegalArgumentException(errorMsg));
return;
}
// As per rule 3.17, when demand overflows `Long.MAX_VALUE`
// we treat the signalled demand as "effectively unbounded"
if (demand.updateAndGet(it -> it == NO_MORE_DEMAND ? it : MathUtils.cappedAdd(it, n)) != NO_MORE_DEMAND)
this.iterate();
}
@Override
public void cancel()
{
cancel(new CancelledException());
}
public void cancel(Throwable cause)
{
// As per rules 3.6 and 3.7, after the Subscription is cancelled all operations MUST be NOPs.
//
// As per rule 3.5, this handles cancellation requests, and is idempotent, thread-safe and not
// synchronously performing heavy computations
if (cancelled.compareAndSet(null, cause))
this.iterate();
}
// Publisher notes
//
// 1.6 If a Publisher signals either onError or onComplete on a Subscriber,
// that Subscribers Subscription MUST be considered cancelled.
// 2.4 Subscriber.onComplete() and Subscriber.onError(Throwable t) MUST consider the
// Subscription cancelled after having received the signal.
//
// Publisher failed -> cancel(Throwable)
// 1.4 If a Publisher fails it MUST signal an onError.
//
// Publisher succeeded -> cancel(COMPLETED)
// 1.5 If a Publisher terminates successfully (finite stream) it MUST signal an onComplete.
// Subscriber
// 2.13 In the case that this rule is violated, any associated Subscription to the Subscriber
// MUST be considered as cancelled, and the caller MUST raise this error condition in a
// fashion that is adequate for the runtime environment.
//
// Subscriber.onSubscribe/onNext/onError/onComplete failed -> cancel(new Suppressed(cause))
// Subscription notes
//
// Subscription.cancel -> cancel(new Cancelled())
// It's not clearly specified in the specification, but according to:
// - the issue: https://github.com/reactive-streams/reactive-streams-jvm/issues/458
// - TCK test 'untested_spec108_possiblyCanceledSubscriptionShouldNotReceiveOnErrorOrOnCompleteSignals'
// - 1.8 If a Subscription is cancelled its Subscriber MUST eventually stop being signaled.
//
// Subscription.request with negative argument -> cancel(err)
// 3.9 While the Subscription is not cancelled, Subscription.request(long n) MUST signal onError with a
// java.lang.IllegalArgumentException if the argument is <= 0.
}
private static class SuppressedException extends Exception
{
SuppressedException(String message)
{
super(message);
}
SuppressedException(Throwable cause)
{
super(cause.getMessage(), cause);
}
}
private void terminate()
private static class CancelledException extends SuppressedException
{
try (AutoLock ignored = lock.lock())
CancelledException()
{
terminated = true;
}
super("Subscription was cancelled");
}
}
}

View File

@ -0,0 +1,251 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.io.content;
import java.nio.ByteBuffer;
import java.util.Random;
import java.util.concurrent.Flow;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.io.Content;
import org.reactivestreams.tck.TestEnvironment;
import org.reactivestreams.tck.flow.FlowPublisherVerification;
import org.testng.annotations.Test;
@Test
public final class ContentSourcePublisherTest extends FlowPublisherVerification<Content.Chunk>
{
public ContentSourcePublisherTest()
{
super(new TestEnvironment());
}
@Override
public Flow.Publisher<Content.Chunk> createFlowPublisher(long elements)
{
Content.Source source = new SyntheticContentSource(elements);
return new ContentSourcePublisher(source);
}
@Override
public Flow.Publisher<Content.Chunk> createFailedFlowPublisher()
{
Content.Source source = new SyntheticContentSource(0);
Flow.Publisher<Content.Chunk> publisher = new ContentSourcePublisher(source);
// Simulate exhausted Content.Source
publisher.subscribe(new Flow.Subscriber<>()
{
@Override
public void onSubscribe(Flow.Subscription subscription)
{
subscription.cancel();
}
@Override
public void onNext(Content.Chunk item)
{
}
@Override
public void onError(Throwable throwable)
{
}
@Override
public void onComplete()
{
}
});
return publisher;
}
private static final class SyntheticContentSource implements Content.Source
{
private final AtomicReference<State> state;
private final long contentSize;
public SyntheticContentSource(long chunksToRead)
{
this.state = new AtomicReference<>(new State.Reading(chunksToRead));
this.contentSize = State.Reading.chunkSize * Math.max(chunksToRead, 0);
}
@Override
public long getLength()
{
return contentSize;
}
@Override
public Content.Chunk read()
{
return state.getAndUpdate(before -> before.read()).chunk();
}
@Override
public void demand(Runnable demandCallback)
{
// recursive stack overflow not necessary for this test
demandCallback.run();
}
@Override
public void fail(Throwable failure)
{
fail(failure, true);
}
@Override
public void fail(Throwable failure, boolean last)
{
state.getAndUpdate(before -> before.fail(failure, last));
}
@Override
public boolean rewind()
{
return false;
}
private sealed interface State permits State.Reading, State.ReadFailed, State.ReadCompleted
{
Content.Chunk chunk();
State read();
State fail(Throwable failure, boolean last);
final class Reading implements State
{
public static final int chunkSize = 16;
private static final Random random = new Random();
private final long chunksToRead;
private final Content.Chunk chunk;
public Reading(long chunksToRead)
{
this.chunksToRead = chunksToRead;
this.chunk = generateValidChunk(chunksToRead);
}
public Reading(long chunksToRead, Throwable transientFailure)
{
this.chunksToRead = chunksToRead;
this.chunk = generateFailureChunk(transientFailure);
}
@Override
public Content.Chunk chunk()
{
return chunk;
}
@Override
public State read()
{
long leftToRead = leftToRead();
if (leftToRead <= 0)
return new ReadCompleted();
return new Reading(leftToRead);
}
@Override
public State fail(Throwable failure, boolean last)
{
if (last)
return new ReadFailed(failure);
return new Reading(chunksToRead, failure);
}
private long leftToRead()
{
if (chunksToRead == Long.MAX_VALUE) // endless source
return chunksToRead;
return chunksToRead - 1;
}
private static Content.Chunk generateFailureChunk(Throwable transientFailure)
{
return Content.Chunk.from(transientFailure, false);
}
private static Content.Chunk generateValidChunk(long chunksToRead)
{
if (chunksToRead <= 0)
return Content.Chunk.EOF;
if (chunksToRead == 1)
return Content.Chunk.from(randomPayload(), true);
return Content.Chunk.from(randomPayload(), false);
}
private static ByteBuffer randomPayload()
{
byte[] payload = new byte[chunkSize];
random.nextBytes(payload);
return ByteBuffer.wrap(payload);
}
}
final class ReadFailed implements State
{
private final Content.Chunk chunk;
public ReadFailed(Throwable failure)
{
this.chunk = Content.Chunk.from(failure, true);
}
@Override
public Content.Chunk chunk()
{
return chunk;
}
@Override
public State read()
{
return this;
}
@Override
public State fail(Throwable failure, boolean last)
{
return this;
}
}
final class ReadCompleted implements State
{
@Override
public Content.Chunk chunk()
{
return Content.Chunk.EOF;
}
@Override
public State read()
{
return this;
}
@Override
public State fail(Throwable failure, boolean last)
{
return this;
}
}
}
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call class="org.eclipse.jetty.keystore.KeystoreGenerator" name="generateTestKeystore">

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://jetty.org/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Get id="ThreadPool" name="threadPool"/>
<New id="HttpClient" class="org.eclipse.jetty.client.HttpClient">

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://jetty.org/configure_9_3.dtd">
<Configure>
<!-- Optional code to configure the base LoginService used by the OpenIdLoginService
<New id="BaseLoginService" class="org.eclipse.jetty.security.HashLoginService">

View File

@ -13,10 +13,14 @@
package org.eclipse.jetty.quic.common;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collection;
import java.util.EventListener;
@ -423,6 +427,31 @@ public abstract class QuicSession extends ContainerLifeCycle
}
}
/**
* <p>Returns the peer certificates chain.</p>
* <p>Due to current Quiche C API limitations (that the Rust version does not have),
* only the last certificate in the chain is returned.
* This may change in the future when the C APIs are aligned to the Rust APIs.</p>
*
* @return the peer certificates chain (currently only the last certificate in the chain)
*/
public X509Certificate[] getPeerCertificates()
{
try
{
byte[] encoded = quicheConnection.getPeerCertificate();
if (encoded == null)
return null;
CertificateFactory factory = CertificateFactory.getInstance("X509");
X509Certificate certificate = (X509Certificate)factory.generateCertificate(new ByteArrayInputStream(encoded));
return new X509Certificate[]{certificate};
}
catch (CertificateException x)
{
return null;
}
}
@Override
public void dump(Appendable out, String indent) throws IOException
{

View File

@ -13,9 +13,11 @@
package org.eclipse.jetty.quic.common;
import java.io.EOFException;
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.stream.IntStream;
@ -40,6 +42,7 @@ public class QuicStreamEndPoint extends AbstractEndPoint
{
private static final Logger LOG = LoggerFactory.getLogger(QuicStreamEndPoint.class);
private static final ByteBuffer LAST_FLAG = ByteBuffer.allocate(0);
private static final ByteBuffer EMPTY_WRITABLE_BUFFER = ByteBuffer.allocate(0);
private final QuicSession session;
private final long streamId;
@ -221,6 +224,15 @@ public class QuicStreamEndPoint extends AbstractEndPoint
return session;
}
@Override
public SslSessionData getSslSessionData()
{
X509Certificate[] peerCertificates = getQuicSession().getPeerCertificates();
if (peerCertificates == null)
return null;
return SslSessionData.from(null, null, null, peerCertificates);
}
public void onWritable()
{
if (LOG.isDebugEnabled())
@ -255,12 +267,25 @@ public class QuicStreamEndPoint extends AbstractEndPoint
}
else
{
QuicStreamEndPoint streamEndPoint = getQuicSession().getStreamEndPoint(streamId);
if (streamEndPoint.isStreamFinished())
if (isStreamFinished())
{
EofException e = new EofException();
streamEndPoint.getFillInterest().onFail(e);
streamEndPoint.getQuicSession().onFailure(e);
// Check if the stream was finished normally.
try
{
fill(EMPTY_WRITABLE_BUFFER);
}
catch (EOFException x)
{
// Got reset.
getFillInterest().onFail(x);
getQuicSession().onFailure(x);
}
catch (Throwable x)
{
EofException e = new EofException(x);
getFillInterest().onFail(e);
getQuicSession().onFailure(e);
}
}
}
return interested;

View File

@ -152,6 +152,8 @@ public abstract class QuicheConnection
public abstract CloseInfo getLocalCloseInfo();
public abstract byte[] getPeerCertificate();
public static class CloseInfo
{
private final long error;

View File

@ -14,6 +14,7 @@
package org.eclipse.jetty.quic.quiche.foreign;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
@ -518,6 +519,7 @@ public class ForeignQuicheConnection extends QuicheConnection
}
}
@Override
public byte[] getPeerCertificate()
{
try (AutoLock ignore = lock.lock())
@ -532,7 +534,7 @@ public class ForeignQuicheConnection extends QuicheConnection
quiche_h.quiche_conn_peer_cert(quicheConn, outSegment, outLenSegment);
long outLen = outLenSegment.get(NativeHelper.C_LONG, 0L);
if (outLen == 0L)
if (outLen <= 0L)
return null;
byte[] out = new byte[(int)outLen];
// dereference outSegment pointer
@ -917,14 +919,19 @@ public class ForeignQuicheConnection extends QuicheConnection
MemorySegment fin = scope.allocate(NativeHelper.C_CHAR);
read = quiche_h.quiche_conn_stream_recv(quicheConn, streamId, bufferSegment, buffer.remaining(), fin);
if (read > 0)
{
int prevPosition = buffer.position();
buffer.put(bufferSegment.asByteBuffer().limit((int)read));
buffer.position(prevPosition);
}
}
}
if (read == quiche_error.QUICHE_ERR_DONE)
return isStreamFinished(streamId) ? -1 : 0;
if (read == quiche_error.QUICHE_ERR_STREAM_RESET)
throw new EOFException("failed to read from stream " + streamId + "; quiche_err=" + quiche_error.errToString(read));
if (read < 0L)
throw new IOException("failed to read from stream " + streamId + "; quiche_err=" + quiche_error.errToString(read));
buffer.position((int)(buffer.position() + read));

View File

@ -14,6 +14,7 @@
package org.eclipse.jetty.quic.quiche.jna;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
@ -413,6 +414,7 @@ public class JnaQuicheConnection extends QuicheConnection
}
}
@Override
public byte[] getPeerCertificate()
{
try (AutoLock ignore = lock.lock())
@ -424,6 +426,8 @@ public class JnaQuicheConnection extends QuicheConnection
size_t_pointer out_len = new size_t_pointer();
LibQuiche.INSTANCE.quiche_conn_peer_cert(quicheConn, out, out_len);
int len = out_len.getPointee().intValue();
if (len <= 0)
return null;
return out.getValueAsBytes(len);
}
}
@ -744,6 +748,8 @@ public class JnaQuicheConnection extends QuicheConnection
int read = LibQuiche.INSTANCE.quiche_conn_stream_recv(quicheConn, new uint64_t(streamId), buffer, new size_t(buffer.remaining()), fin).intValue();
if (read == quiche_error.QUICHE_ERR_DONE)
return isStreamFinished(streamId) ? -1 : 0;
if (read == quiche_error.QUICHE_ERR_STREAM_RESET)
throw new EOFException("failed to read from stream " + streamId + "; quiche_err=" + quiche_error.errToString(read));
if (read < 0L)
throw new IOException("failed to read from stream " + streamId + "; quiche_err=" + quiche_error.errToString(read));
buffer.position(buffer.position() + read);

Some files were not shown because too many files have changed in this diff Show More